home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-27 | 225.9 KB | 5,001 lines | [TEXT/ROSA] |
- Common Lisp the Language, 2nd Edition
- -------------------------------------------------------------------------------
-
- 28. Common Lisp Object System
-
- By Daniel G. Bobrow, Linda G. DeMichiel, Richard P. Gabriel, Sonya E. Keene,
- Gregor Kiczales, and David A. Moon
-
- [change_begin]
- PREFACE: X3J13 voted in June 1988 (CLOS) to adopt the first two chapters (of
- three) of the Common Lisp Object System specification as a part of the
- forthcoming draft Common Lisp standard.
-
- This chapter presents the bulk of the first two chapters of the Common Lisp
- Object System specification; it is substantially identical to these two
- specification chapters as previously published elsewhere [5,6,7]. I have edited
- the material only very lightly to conform to the overall style of this book and
- to save a substantial number of pages by using a typographically condensed
- presentation. I have inserted a small number of bracketed remarks, identified
- by the initials GLS. The chapter divisions of the original specification have
- become section divisions in this chapter; references to the three chapters of
- the original specification now refer to the three ``parts'' of the
- specification. (See the Acknowledgments to this second edition for
- acknowledgments to others who contributed to the Common Lisp Object System
- specification.) This is not the last word on CLOS; X3J13 may well refine this
- material further. Keene has written a good tutorial introduction to CLOS [26].
-
- - Guy L. Steele Jr.
-
- [change_end]
- -------------------------------------------------------------------------------
-
- * Programmer Interface Concepts
- o Error Terminology
- o Classes
- + Defining Classes
- + Creating Instances of Classes
- + Slots
- + Accessing Slots
- o Inheritance
- + Inheritance of Methods
- + Inheritance of Slots and Slot Options
- + Inheritance of Class Options
- + Examples
- o Integrating Types and Classes
- o Determining the Class Precedence List
- + Topological Sorting
- + Examples
- o Generic Functions and Methods
- + Introduction to Generic Functions
- + Introduction to Methods
- + Agreement on Parameter Specializers and Qualifiers
- + Congruent Lambda-Lists for All Methods of a Generic Function
- + Keyword Arguments in Generic Functions and Methods
- o Method Selection and Combination
- + Determining the Effective Method
- + Standard Method Combination
- + Declarative Method Combination
- + Built-in Method Combination Types
- o Meta-objects
- + Metaclasses
- + Standard Metaclasses
- + Standard Meta-objects
- o Object Creation and Initialization
- + Initialization Arguments
- + Declaring the Validity of Initialization Arguments
- + Defaulting of Initialization Arguments
- + Rules for Initialization Arguments
- + Shared-Initialize
- + Initialize-Instance
- + Definitions of Make-Instance and Initialize-Instance
- o Redefining Classes
- + Modifying the Structure of Instances
- + Initializing Newly Added Local Slots
- + Customizing Class Redefinition
- + Extensions
- o Changing the Class of an Instance
- + Modifying the Structure of an Instance
- + Initializing Newly Added Local Slots
- + Customizing the Change of Class of an Instance
- o Reinitializing an Instance
- + Customizing Reinitialization
- * Functions in the Programmer Interface
-
- -------------------------------------------------------------------------------
-
- 28.1. Programmer Interface Concepts
-
- [change_begin]
- The Common Lisp Object System (CLOS) is an object-oriented extension to Common
- Lisp. It is based on generic functions, multiple inheritance, declarative
- method combination, and a meta-object protocol.
-
- The first two parts of this specification describe the standard Programmer
- Interface for the Common Lisp Object System. The first part, Programmer
- Interface Concepts, contains a description of the concepts of the Common Lisp
- Object System, and the second part, Functions in the Programmer Interface,
- contains a description of the functions and macros in the Common Lisp Object
- System Programmer Interface. The third part, The Common Lisp Object System
- Meta-Object Protocol, explains how the Common Lisp Object System can be
- customized. [The third part has not yet been approved by X3J13 for inclusion in
- the forthcoming Common Lisp standard and is not included in this book.-GLS]
-
- The fundamental objects of the Common Lisp Object System are classes,
- instances, generic functions, and methods.
-
- A class object determines the structure and behavior of a set of other objects,
- which are called its instances. Every Common Lisp object is an instance of a
- class. The class of an object determines the set of operations that can be
- performed on the object.
-
- A generic function is a function whose behavior depends on the classes or
- identities of the arguments supplied to it. A generic function object contains
- a set of methods, a lambda-list, a method combination type, and other
- information. The methods define the class-specific behavior and operations of
- the generic function; a method is said to specialize a generic function. When
- invoked, a generic function executes a subset of its methods based on the
- classes of its arguments.
-
- A generic function can be used in the same ways as an ordinary function in
- Common Lisp; in particular, a generic function can be used as an argument to
- funcall and apply and can be given a global or a local name.
-
- A method is an object that contains a method function, a sequence of parameter
- specializers that specify when the given method is applicable, and a sequence
- of qualifiers that is used by the method combination facility to distinguish
- among methods. Each required formal parameter of each method has an associated
- parameter specializer, and the method will be invoked only on arguments that
- satisfy its parameter specializers.
-
- The method combination facility controls the selection of methods, the order in
- which they are run, and the values that are returned by the generic function.
- The Common Lisp Object System offers a default method combination type and
- provides a facility for declaring new types of method combination.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Error Terminology
- * Classes
- o Defining Classes
- o Creating Instances of Classes
- o Slots
- o Accessing Slots
- * Inheritance
- o Inheritance of Methods
- o Inheritance of Slots and Slot Options
- o Inheritance of Class Options
- o Examples
- * Integrating Types and Classes
- * Determining the Class Precedence List
- o Topological Sorting
- o Examples
- * Generic Functions and Methods
- o Introduction to Generic Functions
- o Introduction to Methods
- o Agreement on Parameter Specializers and Qualifiers
- o Congruent Lambda-Lists for All Methods of a Generic Function
- o Keyword Arguments in Generic Functions and Methods
- * Method Selection and Combination
- o Determining the Effective Method
- o Standard Method Combination
- o Declarative Method Combination
- o Built-in Method Combination Types
- * Meta-objects
- o Metaclasses
- o Standard Metaclasses
- o Standard Meta-objects
- * Object Creation and Initialization
- o Initialization Arguments
- o Declaring the Validity of Initialization Arguments
- o Defaulting of Initialization Arguments
- o Rules for Initialization Arguments
- o Shared-Initialize
- o Initialize-Instance
- o Definitions of Make-Instance and Initialize-Instance
- * Redefining Classes
- o Modifying the Structure of Instances
- o Initializing Newly Added Local Slots
- o Customizing Class Redefinition
- o Extensions
- * Changing the Class of an Instance
- o Modifying the Structure of an Instance
- o Initializing Newly Added Local Slots
- o Customizing the Change of Class of an Instance
- * Reinitializing an Instance
- o Customizing Reinitialization
-
- -------------------------------------------------------------------------------
-
- 28.1.1. Error Terminology
-
- [change_begin]
- The terminology used in this chapter to describe erroneous situations differs
- from the terminology used in the first edition. The new terminology involves
- situations; a situation is the evaluation of an expression in some specific
- context. For example, a situation might be the invocation of a function on
- arguments that fail to satisfy some specified constraints.
-
- In the specification of the Common Lisp Object System, the behavior of programs
- in all situations is described, and the options available to the implementor
- are defined. No implementation is allowed to extend the syntax or semantics of
- the Object System except as explicitly defined in the Object System
- specification. In particular, no implementation is allowed to extend the syntax
- of the Object System in such a way that ambiguity between the specified syntax
- of the Object System and those extensions is possible.
-
- ``When situation S occurs, an error is signaled.''
-
- This terminology has the following meaning:
-
- o If this situation occurs, an error will be signaled in the
- interpreter and in code compiled under all compiler safety
- optimization levels.
-
- o Valid programs may rely on the fact that an error will be signaled
- in the interpreter and in code compiled under all compiler safety
- optimization levels.
-
- o Every implementation is required to detect such an error in the
- interpreter and in code compiled under all compiler safety
- optimization levels.
-
- ``When situation S occurs, an error should be signaled.''
-
- This terminology has the following meaning:
-
- o If this situation occurs, an error will be signaled at least in the
- interpreter and in code compiled under the safest compiler safety
- optimization level.
-
- o Valid programs may not rely on the fact that an error will be
- signaled.
-
- o Every implementation is required to detect such an error at least in
- the interpreter and in code compiled under the safest compiler safety
- optimization level.
-
- o When an error is not signaled, the results are undefined (see
- below).
-
- ``When situation S occurs, the results are undefined.''
-
- This terminology has the following meaning:
-
- o If this situation occurs, the results are unpredictable. The results
- may range from harmless to fatal.
-
- o Implementations are allowed to detect this situation and signal an
- error, but no implementation is required to detect the situation.
-
- o No valid program may depend on the effects of this situation, and
- all valid programs are required to treat the effects of this
- situation as unpredictable.
-
- ``When situation S occurs, the results are unspecified.''
-
- This terminology has the following meaning:
-
- o The effects of this situation are not specified in the Object
- System, but the effects are harmless.
-
- o Implementations are allowed to specify the effects of this
- situation.
-
- o No portable program can depend on the effects of this situation, and
- all portable programs are required to treat the situation as
- unpredictable but harmless.
-
- ``The Common Lisp Object System may be extended to cover situation S.''
-
- The meaning of this terminology is that an implementation is free to treat
- situation S in one of three ways:
-
- o When situation S occurs, an error is signaled at least in the
- interpreter and in code compiled under the safest compiler safety
- optimization level.
-
- o When situation S occurs, the results are undefined.
-
- o When situation S occurs, the results are defined and specified.
-
- In addition, this terminology has the following meaning:
-
- o No portable program can depend on the effects of this situation, and
- all portable programs are required to treat the situation as
- undefined.
-
- ``Implementations are free to extend the syntax S.''
-
- This terminology has the following meaning:
-
- o Implementations are allowed to define unambiguous extensions to
- syntax S.
-
- o No portable program can depend on this extension, and all portable
- programs are required to treat the syntax as meaningless.
-
- The Common Lisp Object System specification may disallow certain extensions
- while allowing others.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.2. Classes
-
- [change_begin]
- A class is an object that determines the structure and behavior of a set of
- other objects, which are called its instances.
-
- A class can inherit structure and behavior from other classes. A class whose
- definition refers to other classes for the purpose of inheriting from them is
- said to be a subclass of each of those classes. The classes that are designated
- for purposes of inheritance are said to be superclasses of the inheriting
- class.
-
- A class can have a name. The function class-name takes a class object and
- returns its name. The name of an anonymous class is nil. A symbol can name a
- class. The function find-class takes a symbol and returns the class that the
- symbol names. A class has a proper name if the name is a symbol and if the name
- of the class names that class. That is, a class C has the proper name S if S =
- (class-name C) and C = (find-class S). Notice that it is possible for
- (find-class ) = (find-class ) and . If C = (find-class S), we say that C
- is the class named S.
-
- A class is a direct superclass of a class if explicitly designates
- as a superclass in its definition. In this case, is a direct subclass of .
- A class is a superclass of a class if there exists a series of classes
- such that is a direct superclass of for 1 i < n. In this case, is a
- subclass of . A class is considered neither a superclass nor a subclass of
- itself. That is, if is a superclass of , then . The set of classes
- consisting of some given class C along with all of its superclasses is called
- ``C and its superclasses.''
-
- Each class has a class precedence list, which is a total ordering on the set of
- the given class and its superclasses. The total ordering is expressed as a list
- ordered from most specific to least specific. The class precedence list is used
- in several ways. In general, more specific classes can shadow, or override,
- features that would otherwise be inherited from less specific classes. The
- method selection and combination process uses the class precedence list to
- order methods from most specific to least specific.
-
- When a class is defined, the order in which its direct superclasses are
- mentioned in the defining form is important. Each class has a local precedence
- order, which is a list consisting of the class followed by its direct
- superclasses in the order mentioned in the defining form.
-
- A class precedence list is always consistent with the local precedence order of
- each class in the list. The classes in each local precedence order appear
- within the class precedence list in the same order. If the local precedence
- orders are inconsistent with each other, no class precedence list can be
- constructed, and an error is signaled. The class precedence list and its
- computation is discussed in section 28.1.5.
-
- Classes are organized into a directed acyclic graph. There are two
- distinguished classes, named t and standard-object. The class named t has no
- superclasses. It is a superclass of every class except itself. The class named
- standard-object is an instance of the class standard-class and is a superclass
- of every class that is an instance of standard-class except itself.
-
- There is a mapping from the Common Lisp Object System class space into the
- Common Lisp type space. Many of the standard Common Lisp types have a
- corresponding class that has the same name as the type. Some Common Lisp types
- do not have a corresponding class. The integration of the type and class
- systems is discussed in section 28.1.4.
-
- Classes are represented by objects that are themselves instances of classes.
- The class of the class of an object is termed the metaclass of that object.
- When no misinterpretation is possible, the term metaclass will be used to refer
- to a class that has instances that are themselves classes. The metaclass
- determines the form of inheritance used by the classes that are its instances
- and the representation of the instances of those classes. The Common Lisp
- Object System provides a default metaclass, standard-class, that is appropriate
- for most programs. The meta-object protocol provides mechanisms for defining
- and using new metaclasses.
-
- Except where otherwise specified, all classes mentioned in this chapter are
- instances of the class standard-class, all generic functions are instances of
- the class standard-generic-function, and all methods are instances of the class
- standard-method.
-
- [change_end]
- -------------------------------------------------------------------------------
-
- * Defining Classes
- * Creating Instances of Classes
- * Slots
- * Accessing Slots
-
- -------------------------------------------------------------------------------
-
- 28.1.2.1. Defining Classes
-
- [change_begin]
- The macro defclass is used to define a new named class. The definition of a
- class includes the following:
-
- * The name of the new class. For newly defined classes this is a proper
- name.
-
- * The list of the direct superclasses of the new class.
-
- * A set of slot specifiers. Each slot specifier includes the name of the
- slot and zero or more slot options. A slot option pertains only to a
- single slot. If a class definition contains two slot specifiers with the
- same name, an error is signaled.
-
- * A set of class options. Each class option pertains to the class as a
- whole.
-
- The slot options and class options of the defclass form provide mechanisms for
- the following:
-
- * Supplying a default initial value form for a given slot.
-
- * Requesting that methods for generic functions be automatically generated
- for reading or writing slots.
-
- * Controlling whether a given slot is shared by instances of the class or
- whether each instance of the class has its own slot.
-
- * Supplying a set of initialization arguments and initialization argument
- defaults to be used in instance creation.
-
- * Indicating that the metaclass is to be other than the default.
-
- * Indicating the expected type for the value stored in the slot.
-
- * Indicating the documentation string for the slot.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.2.2. Creating Instances of Classes
-
- [change_begin]
- The generic function make-instance creates and returns a new instance of a
- class. The Object System provides several mechanisms for specifying how a new
- instance is to be initialized. For example, it is possible to specify the
- initial values for slots in newly created instances either by giving arguments
- to make-instance or by providing default initial values.
-
- Further initialization activities can be performed by methods written for
- generic functions that are part of the initialization protocol. The complete
- initialization protocol is described in section 28.1.9.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.2.3. Slots
-
- [change_begin]
- An object that has standard-class as its metaclass has zero or more named
- slots. The slots of an object are determined by the class of the object. Each
- slot can hold one value. The name of a slot is a symbol that is syntactically
- valid for use as a variable name.
-
- When a slot does not have a value, the slot is said to be unbound. When an
- unbound slot is read, the generic function slot-unbound is invoked. The
- system-supplied primary method for slot-unbound signals an error.
-
- The default initial value form for a slot is defined by the :initform slot
- option. When the :initform form is used to supply a value, it is evaluated in
- the lexical environment in which the defclass form was evaluated. The :initform
- along with the lexical environment in which the defclass form was evaluated is
- called a captured :initform. See section 28.1.9.
-
- A local slot is defined to be a slot that is visible to exactly one instance,
- namely the one in which the slot is allocated. A shared slot is defined to be a
- slot that is visible to more than one instance of a given class and its
- subclasses.
-
- A class is said to define a slot with a given name when the defclass form for
- that class contains a slot specifier with that name. Defining a local slot does
- not immediately create a slot; it causes a slot to be created each time an
- instance of the class is created. Defining a shared slot immediately creates a
- slot.
-
- The :allocation slot option to defclass controls the kind of slot that is
- defined. If the value of the :allocation slot option is :instance, a local slot
- is created. If the value of :allocation is :class, a shared slot is created.
-
- A slot is said to be accessible in an instance of a class if the slot is
- defined by the class of the instance or is inherited from a superclass of that
- class. At most one slot of a given name can be accessible in an instance. A
- shared slot defined by a class is accessible in all instances of that class. A
- detailed explanation of the inheritance of slots is given in section 28.1.3.2.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.2.4. Accessing Slots
-
- [change_begin]
- Slots can be accessed in two ways: by use of the primitive function slot-value
- and by use of generic functions generated by the defclass form.
-
- The function slot-value can be used with any slot name specified in the
- defclass form to access a specific slot accessible in an instance of the given
- class.
-
- The macro defclass provides syntax for generating methods to read and write
- slots. If a reader is requested, a method is automatically generated for
- reading the value of the slot, but no method for storing a value into it is
- generated. If a writer is requested, a method is automatically generated for
- storing a value into the slot, but no method for reading its value is
- generated. If an accessor is requested, a method for reading the value of the
- slot and a method for storing a value into the slot are automatically
- generated. Reader and writer methods are implemented using slot-value.
-
- When a reader or writer is specified for a slot, the name of the generic
- function to which the generated method belongs is directly specified. If the
- name specified for the writer option is the symbol name, the name of the
- generic function for writing the slot is the symbol name, and the generic
- function takes two arguments: the new value and the instance, in that order. If
- the name specified for the accessor option is the symbol name, the name of the
- generic function for reading the slot is the symbol name, and the name of the
- generic function for writing the slot is the list (setf name).
-
- A generic function created or modified by supplying reader, writer, or accessor
- slot options can be treated exactly as an ordinary generic function.
-
- Note that slot-value can be used to read or write the value of a slot whether
- or not reader or writer methods exist for that slot. When slot-value is used,
- no reader or writer methods are invoked.
-
- The macro with-slots can be used to establish a lexical environment in which
- specified slots are lexically available as if they were variables. The macro
- with-slots invokes the function slot-value to access the specified slots.
-
- The macro with-accessors can be used to establish a lexical environment in
- which specified slots are lexically available through their accessors as if
- they were variables. The macro with-accessors invokes the appropriate accessors
- to access the specified slots. Any accessors specified by with-accessors must
- already have been defined before they are used.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.3. Inheritance
-
- [change_begin]
- A class can inherit methods, slots, and some defclass options from its
- superclasses. The following sections describe the inheritance of methods, the
- inheritance of slots and slot options, and the inheritance of class options.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Inheritance of Methods
- * Inheritance of Slots and Slot Options
- * Inheritance of Class Options
- * Examples
-
- -------------------------------------------------------------------------------
-
- 28.1.3.1. Inheritance of Methods
-
- [change_begin]
- A subclass inherits methods in the sense that any method applicable to all
- instances of a class is also applicable to all instances of any subclass of
- that class.
-
- The inheritance of methods acts the same way regardless of whether the method
- was created by using one of the method-defining forms or by using one of the
- defclass options that causes methods to be generated automatically.
-
- The inheritance of methods is described in detail in section 28.1.7.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.3.2. Inheritance of Slots and Slot Options
-
- [change_begin]
- The set of names of all slots accessible in an instance of a class C is the
- union of the sets of names of slots defined by C and its superclasses. The
- structure of an instance is the set of names of local slots in that instance.
-
- In the simplest case, only one class among C and its superclasses defines a
- slot with a given slot name. If a slot is defined by a superclass of C, the
- slot is said to be inherited. The characteristics of the slot are determined by
- the slot specifier of the defining class. Consider the defining class for a
- slot S. If the value of the :allocation slot option is :instance, then S is a
- local slot and each instance of C has its own slot named S that stores its own
- value. If the value of the :allocation slot option is :class, then S is a
- shared slot, the class that defined S stores the value, and all instances of C
- can access that single slot. If the :allocation slot option is omitted,
- :instance is used.
-
- In general, more than one class among C and its superclasses can define a slot
- with a given name. In such cases, only one slot with the given name is
- accessible in an instance of C, and the characteristics of that slot are a
- combination of the several slot specifiers, computed as follows:
-
- * All the slot specifiers for a given slot name are ordered from most
- specific to least specific, according to the order in C's class precedence
- list of the classes that define them. All references to the specificity of
- slot specifiers immediately following refer to this ordering.
-
- * The allocation of a slot is controlled by the most specific slot
- specifier. If the most specific slot specifier does not contain an
- :allocation slot option, :instance is used. Less specific slot specifiers
- do not affect the allocation.
-
- * The default initial value form for a slot is the value of the :initform
- slot option in the most specific slot specifier that contains one. If no
- slot specifier contains an :initform slot option, the slot has no default
- initial value form.
-
- * The contents of a slot will always be of type (and ... ) where
- are the values of the :type slot options contained in all of the slot
- specifiers. If no slot specifier contains the :type slot option, the
- contents of the slot will always be of type t. The result of attempting to
- store in a slot a value that does not satisfy the type of the slot is
- undefined.
-
- * The set of initialization arguments that initialize a given slot is the
- union of the initialization arguments declared in the :initarg slot
- options in all the slot specifiers.
-
- * The documentation string for a slot is the value of the :documentation
- slot option in the most specific slot specifier that contains one. If no
- slot specifier contains a :documentation slot option, the slot has no
- documentation string.
-
- A consequence of the allocation rule is that a shared slot can be shadowed. For
- example, if a class defines a slot named S whose value for the :allocation
- slot option is :class, that slot is accessible in instances of and all of
- its subclasses. However, if is a subclass of and also defines a slot
- named S, 's slot is not shared by instances of and its subclasses. When a
- class defines a shared slot, any subclass of will share this single
- slot unless the defclass form for specifies a slot of the same name or there
- is a superclass of that precedes in the class precedence list of that
- defines a slot of the same name.
-
- A consequence of the type rule is that the value of a slot satisfies the type
- constraint of each slot specifier that contributes to that slot. Because the
- result of attempting to store in a slot a value that does not satisfy the type
- constraint for the slot is undefined, the value in a slot might fail to satisfy
- its type constraint.
-
- The :reader, :writer, and :accessor slot options create methods rather than
- define the characteristics of a slot. Reader and writer methods are inherited
- in the sense described in section 28.1.3.1.
-
- Methods that access slots use only the name of the slot and the type of the
- slot's value. Suppose a superclass provides a method that expects to access a
- shared slot of a given name, and a subclass defines a local slot with the same
- name. If the method provided by the superclass is used on an instance of the
- subclass, the method accesses the local slot.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.3.3. Inheritance of Class Options
-
- [change_begin]
- The :default-initargs class option is inherited. The set of defaulted
- initialization arguments for a class is the union of the sets of initialization
- arguments specified in the :default-initargs class options of the class and its
- superclasses. When more than one default initial value form is supplied for a
- given initialization argument, the default initial value form that is used is
- the one supplied by the class that is most specific according to the class
- precedence list.
-
- If a given :default-initargs class option specifies an initialization argument
- of the same name more than once, an error is signaled.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.3.4. Examples
-
- [change_begin]
-
- (defclass C1 ()
- ((S1 :initform 5.4 :type number)
- (S2 :allocation :class)))
-
- (defclass C2 (C1)
- ((S1 :initform 5 :type integer)
- (S2 :allocation :instance)
- (S3 :accessor C2-S3)))
-
- Instances of the class C1 have a local slot named S1, whose default initial
- value is 5.4 and whose value should always be a number. The class C1 also has a
- shared slot named S2.
-
- There is a local slot named S1 in instances of C2. The default initial value of
- S1 is 5. The value of S1 will be of type (and integer number). There are also
- local slots named S2 and S3 in instances of C2. The class C2 has a method for
- C2-S3 for reading the value of slot S3; there is also a method for (setf C2-S3)
- that writes the value of S3.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.4. Integrating Types and Classes
-
- [change_begin]
- The Common Lisp Object System maps the space of classes into the Common Lisp
- type space. Every class that has a proper name has a corresponding type with
- the same name.
-
- The proper name of every class is a valid type specifier. In addition, every
- class object is a valid type specifier. Thus the expression (typep object
- class) evaluates to true if the class of object is class itself or a subclass
- of class. The evaluation of the expression (subtypep class1 class2) returns the
- values t and t if class1 is a subclass of class2 or if they are the same class;
- otherwise it returns the values nil and t. If I is an instance of some class C
- named S and C is an instance of standard-class, the evaluation of the
- expression (type-of I) will return S if S is the proper name of C; if S is not
- the proper name of C, the expression (type-of I) will return C.
-
- Because the names of classes and class objects are type specifiers, they may be
- used in the special form the and in type declarations.
-
- Many but not all of the predefined Common Lisp type specifiers have a
- corresponding class with the same proper name as the type. These type
- specifiers are listed in table 28-1. For example, the type array has a
- corresponding class named array. No type specifier that is a list, such as
- (vector double-float 100), has a corresponding class. The form deftype does not
- create any classes.
-
- Each class that corresponds to a predefined Common Lisp type specifier can be
- implemented in one of three ways, at the discretion of each implementation. It
- can be a standard class (of the kind defined by defclass), a structure class
- (defined by defstruct), or a built-in class (implemented in a special,
- non-extensible way).
-
- A built-in class is one whose instances have restricted capabilities or special
- representations. Attempting to use defclass to define subclasses of a built-in
- class signals an error. Calling make-instance to create an instance of a
- built-in class signals an error. Calling slot-value on an instance of a
- built-in class signals an error. Redefining a built-in class or using
- change-class to change the class of an instance to or from a built-in class
- signals an error. However, built-in classes can be used as parameter
- specializers in methods.
-
- It is possible to determine whether a class is a built-in class by checking the
- metaclass. A standard class is an instance of standard-class, a built-in class
- is an instance of built-in-class, and a structure class is an instance of
- structure-class.
-
- Each structure type created by defstruct without using the :type option has a
- corresponding class. This class is an instance of structure-class.
-
- The :include option of defstruct creates a direct subclass of the class that
- corresponds to the included structure.
-
- The purpose of specifying that many of the standard Common Lisp type specifiers
- have a corresponding class is to enable users to write methods that
- discriminate on these types. Method selection requires that a class precedence
- list can be determined for each class.
-
- The hierarchical relationships among the Common Lisp type specifiers are
- mirrored by relationships among the classes corresponding to those types. The
- existing type hierarchy is used for determining the class precedence list for
- each class that corresponds to a predefined Common Lisp type. In some cases,
- the first edition did not specify a local precedence order for two supertypes
- of a given type specifier. For example, null is a subtype of both symbol and
- list, but the first edition did not specify whether symbol is more specific or
- less specific than list. The CLOS specification defines those relationships for
- all such classes.
-
- Table 28-1 lists the set of classes required by the Object System that
- correspond to predefined Common Lisp type specifiers. The superclasses of each
- such class are presented in order from most specific to most general, thereby
- defining the class precedence list for the class. The local precedence order
- for each class that corresponds to a Common Lisp type specifier can be derived
- from this table.
-
- Individual implementations may be extended to define other type specifiers to
- have a corresponding class. Individual implementations can be extended to add
- other subclass relationships and to add other elements to the class precedence
- lists in the above table as long as they do not violate the type relationships
- and disjointness requirements specified in section 2.15. A standard class
- defined with no direct superclasses is guaranteed to be disjoint from all of
- the classes in the table, except for the class named t.
-
- [At this point the original CLOS report specified that certain Common Lisp
- types were to appear in table 28-1 if and only if X3J13 voted to make them
- disjoint from cons, symbol, array, number, and character. X3J13 voted to do so
- in June 1988 (DATA-TYPES-HIERARCHY-UNDERSPECIFIED) . I have added these types
- and their class precedence lists to the table; the new types are indicated by
- asterisks.-GLS]
-
-
- ----------------------------------------------------------------
- Table 28-1: Class Precedence Lists for Predefined Types
-
- Predefined Class Precedence List
- Common Lisp Type for Corresponding Class
- ==============================================================
- array (array t)
- bit-vector (bit-vector vector array sequence t)
- character (character t)
- complex (complex number t)
- cons (cons list sequence t)
- float (float number t)
- function * (function t)
- hash-table * (hash-table t)
- integer (integer rational number t)
- list (list sequence t)
- null (null symbol list sequence t)
- number (number t)
- package * (package t)
- pathname * (pathname t)
- random-state * (random-state t)
- ratio (ratio rational number t)
- rational (rational number t)
- readtable * (readtable t)
- sequence (sequence t)
- stream * (stream t)
- string (string vector array sequence t)
- symbol (symbol t)
- t (t)
- vector (vector array sequence t)
- ==============================================================
-
- [An asterisk indicates a type added to this table as a consequence of
- a portion of the CLOS specification that was conditional on X3J13
- voting to make that type disjoint from certain other built-in types
- (DATA-TYPES-HIERARCHY-UNDERSPECIFIED).---GLS]
-
- ----------------------------------------------------------------
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.5. Determining the Class Precedence List
-
- [change_begin]
- The defclass form for a class provides a total ordering on that class and its
- direct superclasses. This ordering is called the local precedence order. It is
- an ordered list of the class and its direct superclasses. The class precedence
- list for a class C is a total ordering on C and its superclasses that is
- consistent with the local precedence orders for C and its superclasses.
-
- A class precedes its direct superclasses, and a direct superclass precedes all
- other direct superclasses specified to its right in the superclasses list of
- the defclass form. For every class C, define
-
-
-
- where are the direct superclasses of C in the order in which they are
- mentioned in the defclass form. These ordered pairs generate the total ordering
- on the class C and its direct superclasses.
-
- Let be the set of C and its superclasses. Let R be
-
-
-
- The set R may or may not generate a partial ordering, depending on whether the
- , , are consistent; it is assumed that they are consistent and that R
- generates a partial ordering. When the are not consistent, it is said that R
- is inconsistent.
-
- To compute the class precedence list for C, topologically sort the elements of
- with respect to the partial ordering generated by R. When the topological
- sort must select a class from a set of two or more classes, none of which are
- preceded by other classes with respect to R, the class selected is chosen
- deterministically, as described below. If R is inconsistent, an error is
- signaled.
-
- [change_end]
- -------------------------------------------------------------------------------
-
- * Topological Sorting
- * Examples
-
- -------------------------------------------------------------------------------
-
- 28.1.5.1. Topological Sorting
-
- [change_begin]
- Topological sorting proceeds by finding a class C in such that no other
- class precedes that element according to the elements in R. The class C is
- placed first in the result. Remove C from , and remove all pairs of the form
- (C, D), , from R. Repeat the process, adding classes with no predecessors to
- the end of the result. Stop when no element can be found that has no
- predecessor.
-
- If is not empty and the process has stopped, the set R is inconsistent. If
- every class in the finite set of classes is preceded by another, then R
- contains a loop. That is, there is a chain of classes such that precedes
- , 1 <= i < n, and precedes .
-
- Sometimes there are several classes from with no predecessors. In this case
- select the one that has a direct subclass rightmost in the class precedence
- list computed so far.
-
- If there is no such candidate class, R does not generate a partial ordering -
- the , , are inconsistent.
-
- In more precise terms, let , m >= 2, be the classes from with no
- predecessors. Let , n >= 1, be the class precedence list constructed so far.
- is the most specific class, and is the least specific. Let 1 <= j <= n be
- the largest number such that there exists an i where 1 <= i <= m and is a
- direct superclass of ; is placed next.
-
- The effect of this rule for selecting from a set of classes with no
- predecessors is that classes in a simple superclass chain are adjacent in the
- class precedence list and that classes in each relatively separated subgraph
- are adjacent in the class precedence list. For example, let and be
- subgraphs whose only element in common is the class J. Suppose that no
- superclass of J appears in either or . Let be the bottom of ; and let
- be the bottom of . Suppose C is a class whose direct superclasses are
- and in that order; then the class precedence list for C will start with C
- and will be followed by all classes in except J. All the classes of will
- be next. The class J and its superclasses will appear last.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.5.2. Examples
-
- [change_begin]
- This example determines a class precedence list for the class pie. The
- following classes are defined:
-
- (defclass pie (apple cinnamon) ())
- (defclass apple (fruit) ())
- (defclass cinnamon (spice) ())
- (defclass fruit (food) ())
- (defclass spice (food) ())
- (defclass food () ())
-
- The set S = {pie, apple, cinnamon, fruit, spice, food, standard-object, t}. The
- set R = {(pie, apple), (apple, cinnamon), (cinnamon, standard-object), (apple,
- fruit), (fruit, standard-object), (cinnamon, spice), (spice, standard-object),
- (fruit, food), (food, standard-object), (spice, food), (standard-object, t)}
-
- [The original CLOS specification [5,6] contained a minor error in this example:
- the pairs (cinnamon, standard-object), (fruit, standard-object), and (spice,
- standard-object) were inadvertently omitted from R in the preceding paragraph.
- It is important to understand that defclass implicitly appends the class
- standard-object to the list of superclasses when the metaclass is
- standard-class (the normal situation), in order to insure that standard-object
- will be a superclass of every instance of standard-class except standard-object
- itself (see section 28.1.2). is then generated from this augmented list of
- superclasses; this is where the extra pairs come from. I have corrected the
- example by adding these pairs as appropriate throughout the example. The final
- result, the class precedence list for pie, is unchanged.-GLS]
-
- The class pie is not preceded by anything, so it comes first; the result so far
- is (pie). Remove pie from S and pairs mentioning pie from R to get
- S = {apple, cinnamon, fruit, spice, food, standard-object, t} and R = {(apple,
- cinnamon), (cinnamon, standard-object), (apple, fruit), (fruit,
- standard-object), (cinnamon, spice), (spice, standard-object), (fruit, food),
- (food, standard-object), (spice, food), (standard-object, t)}.
-
- The class apple is not preceded by anything, so it is next; the result is (pie
- apple). Removing apple and the relevant pairs results in
- S = {cinnamon, fruit, spice, food, standard-object, t} and R = {(cinnamon,
- standard-object), (fruit, standard-object), (cinnamon, spice), (spice,
- standard-object), (fruit, food), (food, standard-object), (spice, food),
- (standard-object, t)}.
-
- The classes cinnamon and fruit are not preceded by anything, so the one with a
- direct subclass rightmost in the class precedence list computed so far goes
- next. The class apple is a direct subclass of fruit, and the class pie is a
- direct subclass of cinnamon. Because apple appears to the right of pie in the
- precedence list, fruit goes next, and the result so far is (pie apple fruit).
- S = {cinnamon, spice, food, standard-object, t} and R = {(cinnamon,
- standard-object), (cinnamon, spice), (spice, standard-object), (food,
- standard-object), (spice, food), (standard-object, t)}.
-
- The class cinnamon is next, giving the result so far as (pie apple fruit
- cinnamon). At this point
- S = {spice, food, standard-object, t} and R = {(spice, standard-object), (food,
- standard-object), (spice, food), (standard-object, t)}.
-
- The classes spice, food, standard-object, and t are then added in that order,
- and the final class precedence list for pie is
-
- (pie apple fruit cinnamon spice food standard-object t)
-
- It is possible to write a set of class definitions that cannot be ordered. For
- example:
-
- (defclass new-class (fruit apple) ())
- (defclass apple (fruit) ())
-
- The class fruit must precede apple because the local ordering of superclasses
- must be preserved. The class apple must precede fruit because a class always
- precedes its own superclasses. When this situation occurs, an error is signaled
- when the system tries to compute the class precedence list.
-
- The following might appear to be a conflicting set of definitions:
-
- (defclass pie (apple cinnamon) ())
- (defclass pastry (cinnamon apple) ())
- (defclass apple () ())
- (defclass cinnamon () ())
-
- The class precedence list for pie is
-
- (pie apple cinnamon standard-object t)
-
- The class precedence list for pastry is
-
- (pastry cinnamon apple standard-object t)
-
- It is not a problem for apple to precede cinnamon in the ordering of the
- superclasses of pie but not in the ordering for pastry. However, it is not
- possible to build a new class that has both pie and pastry as superclasses.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.6. Generic Functions and Methods
-
- [change_begin]
- A generic function is a function whose behavior depends on the classes or
- identities of the arguments supplied to it. The methods define the
- class-specific behavior and operations of the generic function. The following
- sections describe generic functions and methods.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Introduction to Generic Functions
- * Introduction to Methods
- * Agreement on Parameter Specializers and Qualifiers
- * Congruent Lambda-Lists for All Methods of a Generic Function
- * Keyword Arguments in Generic Functions and Methods
-
- -------------------------------------------------------------------------------
-
- 28.1.6.1. Introduction to Generic Functions
-
- [change_begin]
- A generic function object contains a set of methods, a lambda-list, a method
- combination type, and other information.
-
- Like an ordinary Lisp function, a generic function takes arguments, performs a
- series of operations, and perhaps returns useful values. An ordinary function
- has a single body of code that is always executed when the function is called.
- A generic function has a set of bodies of code of which a subset is selected
- for execution. The selected bodies of code and the manner of their combination
- are determined by the classes or identities of one or more of the arguments to
- the generic function and by its method combination type.
-
- Ordinary functions and generic functions are called with identical
- function-call syntax.
-
- Generic functions are true functions that can be passed as arguments, returned
- as values, used as the first argument to funcall and apply, and otherwise used
- in all the ways an ordinary function may be used.
-
- A name can be given to an ordinary function in one of two ways: a global name
- can be given to a function using the defun construct; a local name can be given
- using the flet or labels special forms. A generic function can be given a
- global name using the defmethod or defgeneric construct. A generic function can
- be given a local name using the generic-flet, generic-labels, or
- with-added-methods special forms. The name of a generic function, like the name
- of an ordinary function, can be either a symbol or a two-element list whose
- first element is setf and whose second element is a symbol. This is true for
- both local and global names.
-
- The generic-flet special form creates new local generic functions using the set
- of methods specified by the method definitions in the generic-flet form. The
- scoping of generic function names within a generic-flet form is the same as for
- flet.
-
- The generic-labels special form creates a set of new mutually recursive local
- generic functions using the set of methods specified by the method definitions
- in the generic-labels form. The scoping of generic function names within a
- generic-labels form is the same as for labels.
-
- The with-added-methods special form creates new local generic functions by
- adding the set of methods specified by the method definitions with a given name
- in the with-added-methods form to copies of the methods of the lexically
- visible generic function of the same name. If there is a lexically visible
- ordinary function of the same name as one of the specified generic functions,
- that function becomes the method function of the default method for the new
- generic function of that name.
-
- The generic-function macro creates an anonymous generic function with the set
- of methods specified by the method definitions that appear in the
- generic-function form.
-
- When a defgeneric form is evaluated, one of three actions is taken:
-
- * If a generic function of the given name already exists, the existing
- generic function object is modified. Methods specified by the current
- defgeneric form are added, and any methods in the existing generic
- function that were defined by a previous defgeneric form are removed.
- Methods added by the current defgeneric form might replace methods defined
- by defmethod or defclass. No other methods in the generic function are
- affected or replaced.
-
- * If the given name names a non-generic function, a macro, or a special
- form, an error is signaled.
-
- * Otherwise a generic function is created with the methods specified by the
- method definitions in the defgeneric form.
-
- Some forms specify the options of a generic function, such as the type of
- method combination it uses or its argument precedence order. They will be
- referred to as ``forms that specify generic function options.'' These forms are
- defgeneric, generic-function, generic-flet, generic-labels, and
- with-added-methods.
-
- Some forms define methods for a generic function. They will be referred to as
- ``method-defining forms.'' These forms are defgeneric, defmethod,
- generic-function, generic-flet, generic-labels, with-added-methods, and
- defclass. Note that all the method-defining forms except defclass and defmethod
- are also forms that specify generic function options.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.6.2. Introduction to Methods
-
- [change_begin]
- A method object contains a method function, a sequence of parameter
- specializers that specify when the given method is applicable, a lambda-list,
- and a sequence of qualifiers that are used by the method combination facility
- to distinguish among methods.
-
- A method object is not a function and cannot be invoked as a function. Various
- mechanisms in the Object System take a method object and invoke its method
- function, as is the case when a generic function is invoked. When this occurs
- it is said that the method is invoked or called.
-
- A method-defining form contains the code that is to be run when the arguments
- to the generic function cause the method that it defines to be invoked. When a
- method-defining form is evaluated, a method object is created and one of four
- actions is taken:
-
- * If a generic function of the given name already exists and if a method
- object already exists that agrees with the new one on parameter
- specializers and qualifiers, the new method object replaces the old one.
- For a definition of one method agreeing with another on parameter
- specializers and qualifiers, see section 28.1.6.3.
-
- * If a generic function of the given name already exists and if there is no
- method object that agrees with the new one on parameter specializers and
- qualifiers, the existing generic function object is modified to contain
- the new method object.
-
- * If the given name names a non-generic function, a macro, or a special
- form, an error is signaled.
-
- * Otherwise a generic function is created with the methods specified by the
- method-defining form.
-
- If the lambda-list of a new method is not congruent with the lambda-list of the
- generic function, an error is signaled. If a method-defining form that cannot
- specify generic function options creates a new generic function, a lambda-list
- for that generic function is derived from the lambda-lists of the methods in
- the method-defining form in such a way as to be congruent with them. For a
- discussion of congruence, see section 28.1.6.4.
-
- Each method has a specialized lambda-list, which determines when that method
- can be applied. A specialized lambda-list is like an ordinary lambda-list
- except that a specialized parameter may occur instead of the name of a required
- parameter. A specialized parameter is a list (variable-name
- parameter-specializer-name), where parameter-specializer-name is either a name
- that names a class or a list (eql form). A parameter specializer name denotes a
- parameter specializer as follows:
-
- * A name that names a class denotes that class.
-
- * The list (eql form) denotes the type specifier (eql object), where object
- is the result of evaluating form. The form form is evaluated in the
- lexical environment in which the method-defining form is evaluated. Note
- that form is evaluated only once, at the time the method is defined, not
- each time the generic function is called.
-
- Parameter specializer names are used in macros intended as the user-level
- interface (defmethod), while parameter specializers are used in the functional
- interface.
-
- [It is very important to understand clearly the distinction made in the
- preceding paragraph. A parameter specializer name has the form of a type
- specifier but is semantically quite different from a type specifier: a
- parameter specializer name of the form (eql form) is not a type specifier, for
- it contains a form to be evaluated. Type specifiers never contain forms to be
- evaluated. All parameter specializers (as opposed to parameter specializer
- names) are valid type specifiers, but not all type specifiers are valid
-
- names and treat them as specifications for constructing certain type specifiers
- (parameter specializers) that may then be used with such functions as
- find-method.-GLS]
-
- Only required parameters may be specialized, and there must be a parameter
- specializer for each required parameter. For notational simplicity, if some
- required parameter in a specialized lambda-list in a method-defining form is
- simply a variable name, its parameter specializer defaults to the class named
- t.
-
- Given a generic function and a set of arguments, an applicable method is a
- method for that generic function whose parameter specializers are satisfied by
- their corresponding arguments. The following definition specifies what it means
- for a method to be applicable and for an argument to satisfy a parameter
- specializer.
-
- Let be the required arguments to a generic function in order. Let be the
- parameter specializers corresponding to the required parameters of the method M
- in order. The method M is applicable when each satisfies . If is a
- class, and if is an instance of a class C, then it is said that satisfies
- when or when C is a subclass of . If is of the form (eql object),
- then it is said that satisfies when the function eql applied to and
- object is true.
-
- Because a parameter specializer is a type specifier, the function typep can be
- used during method selection to determine whether an argument satisfies a
- parameter specializer. In general a parameter specializer cannot be a type
- specifier list, such as (vector single-float). The only parameter specializer
- that can be a list is (eql object). This requires that Common Lisp define the
- type specifier eql as if the following were evaluated:
-
- (deftype eql (object) `(member ,object))
-
- [See section 4.3.-GLS]
-
- A method all of whose parameter specializers are the class named t is called a
- default method; it is always applicable but may be shadowed by a more specific
- method.
-
- Methods can have qualifiers, which give the method combination procedure a way
- to distinguish among methods. A method that has one or more qualifiers is
- called a qualified method. A method with no qualifiers is called an unqualified
- method. A qualifier is any object other than a list, that is, any non-nil atom.
- The qualifiers defined by standard method combination and by the built-in
- method combination types are symbols.
-
- In this specification, the terms primary method and auxiliary method are used
- to partition methods within a method combination type according to their
- intended use. In standard method combination, primary methods are unqualified
- methods, and auxiliary methods are methods with a single qualifier that is one
- of :around, :before, or :after. When a method combination type is defined using
- the short form of define-method-combination, primary methods are methods
- qualified with the name of the type of method combination, and auxiliary
- methods have the qualifier :around. Thus the terms primary method and auxiliary
- method have only a relative definition within a given method combination type.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.6.3. Agreement on Parameter Specializers and Qualifiers
-
- [change_begin]
- Two methods are said to agree with each other on parameter specializers and
- qualifiers if the following conditions hold:
-
- * Both methods have the same number of required parameters. Suppose the
- parameter specializers of the two methods are and .
-
- * For each 1 <= i <= n, agrees with . The parameter specializer
- agrees with if and are the same class or if , , and (eql
- ). Otherwise and do not agree.
-
- * The lists of qualifiers of both methods contain the same non-nil atoms in
- the same order. That is, the lists are equal.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.6.4. Congruent Lambda-Lists for All Methods of a Generic Function
-
- [change_begin]
- These rules define the congruence of a set of lambda-lists, including the
- lambda-list of each method for a given generic function and the lambda-list
- specified for the generic function itself, if given.
-
- * Each lambda-list must have the same number of required parameters.
-
- * Each lambda-list must have the same number of optional parameters. Each
- method can supply its own default for an optional parameter.
-
- * If any lambda-list mentions &rest or &key, each lambda-list must mention
- one or both of them.
-
- * If the generic function lambda-list mentions &key, each method must
- accept all of the keyword names mentioned after &key, either by accepting
- them explicitly, by specifying &allow-other-keys, or by specifying &rest
- but not &key. Each method can accept additional keyword arguments of its
- own. The checking of the validity of keyword names is done in the generic
- function, not in each method. A method is invoked as if the keyword
- argument pair whose keyword is :allow-other-keys and whose value is t were
- supplied, though no such argument pair will be passed.
-
- * The use of &allow-other-keys need not be consistent across lambda-lists.
- If &allow-other-keys is mentioned in the lambda-list of any applicable
- method or of the generic function, any keyword arguments may be mentioned
- in the call to the generic function.
-
- * The use of &aux need not be consistent across methods.
-
- If a method-defining form that cannot specify generic function options creates
- a generic function, and if the lambda-list for the method mentions keyword
- arguments, the lambda-list of the generic function will mention &key (but no
- keyword arguments).
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.6.5. Keyword Arguments in Generic Functions and Methods
-
- [change_begin]
- When a generic function or any of its methods mentions &key in a lambda-list,
- the specific set of keyword arguments accepted by the generic function varies
- according to the applicable methods. The set of keyword arguments accepted by
- the generic function for a particular call is the union of the keyword
- arguments accepted by all applicable methods and the keyword arguments
- mentioned after &key in the generic function definition, if any. A method that
- has &rest but not &key does not affect the set of acceptable keyword arguments.
- If the lambda-list of any applicable method or of the generic function
- definition contains &allow-other-keys, all keyword arguments are accepted by
- the generic function.
-
- The lambda-list congruence rules require that each method accept all of the
- keyword arguments mentioned after &key in the generic function definition, by
- accepting them explicitly, by specifying &allow-other-keys, or by specifying
- &rest but not &key. Each method can accept additional keyword arguments of its
- own, in addition to the keyword arguments mentioned in the generic function
- definition.
-
- If a generic function is passed a keyword argument that no applicable method
- accepts, an error is signaled.
-
- For example, suppose there are two methods defined for width as follows:
-
- (defmethod width ((c character-class) &key font) ...)
-
- (defmethod width ((p picture-class) &key pixel-size) ...)
-
- Assume that there are no other methods and no generic function definition for
- width. The evaluation of the following form will signal an error because the
- keyword argument :pixel-size is not accepted by the applicable method.
-
- (width (make-instance 'character-class :char #\Q)
- :font 'baskerville :pixel-size 10)
-
- The evaluation of the following form will signal an error.
-
- (width (make-instance 'picture-class :glyph (glyph #\Q))
- :font 'baskerville :pixel-size 10)
-
- The evaluation of the following form will not signal an error if the class
- named character-picture-class is a subclass of both picture-class and
- character-class.
-
- (width (make-instance 'character-picture-class :char #\Q)
- :font 'baskerville :pixel-size 10)
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.7. Method Selection and Combination
-
- [change_begin]
- When a generic function is called with particular arguments, it must determine
- the code to execute. This code is called the effective method for those
- arguments. The effective method is a combination of the applicable methods in
- the generic function. A combination of methods is a Lisp expression that
- contains calls to some or all of the methods. If a generic function is called
- and no methods apply, the generic function no-applicable-method is invoked.
-
- When the effective method has been determined, it is invoked with the same
- arguments that were passed to the generic function. Whatever values it returns
- are returned as the values of the generic function.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Determining the Effective Method
- * Standard Method Combination
- * Declarative Method Combination
- * Built-in Method Combination Types
-
- -------------------------------------------------------------------------------
-
- 28.1.7.1. Determining the Effective Method
-
- [change_begin]
- The effective method for a set of arguments is determined by the following
- three-step procedure:
-
- 1. Select the applicable methods.
-
- 2. Sort the applicable methods by precedence order, putting the most
- specific method first.
-
- 3. Apply method combination to the sorted list of applicable methods,
- producing the effective method.
-
- Selecting the Applicable Methods. This step is described in section 28.1.6.2.
-
- Sorting the Applicable Methods by Precedence Order. To compare the precedence
- of two methods, their parameter specializers are examined in order. The default
- examination order is from left to right, but an alternative order may be
- specified by the :argument-precedence-order option to defgeneric or to any of
- the other forms that specify generic function options.
-
- The corresponding parameter specializers from each method are compared. When a
- pair of parameter specializers are equal, the next pair are compared for
- equality. If all corresponding parameter specializers are equal, the two
- methods must have different qualifiers; in this case, either method can be
- selected to precede the other.
-
- If some corresponding parameter specializers are not equal, the first pair of
- parameter specializers that are not equal determines the precedence. If both
- parameter specializers are classes, the more specific of the two methods is the
- method whose parameter specializer appears earlier in the class precedence list
- of the corresponding argument. Because of the way in which the set of
- applicable methods is chosen, the parameter specializers are guaranteed to be
- present in the class precedence list of the class of the argument.
-
- If just one parameter specializer is (eql object), the method with that
- parameter specializer precedes the other method. If both parameter specializers
- are eql forms, the specializers must be the same (otherwise the two methods
- would not both have been applicable to this argument).
-
- The resulting list of applicable methods has the most specific method first and
- the least specific method last.
-
- Applying Method Combination to the Sorted List of Applicable Methods. In the
- simple case-if standard method combination is used and all applicable methods
- are primary methods-the effective method is the most specific method. That
- method can call the next most specific method by using the function
- call-next-method. The method that call-next-method will call is referred to as
- the next method. The predicate next-method-p tests whether a next method
- exists. If call-next-method is called and there is no next most specific
- method, the generic function no-next-method is invoked.
-
- In general, the effective method is some combination of the applicable methods.
- It is defined by a Lisp form that contains calls to some or all of the
- applicable methods, returns the value or values that will be returned as the
- value or values of the generic function, and optionally makes some of the
- methods accessible by means of call-next-method. This Lisp form is the body of
- the effective method; it is augmented with an appropriate lambda-list to make
- it a function.
-
- The role of each method in the effective method is determined by its method
- qualifiers and the specificity of the method. A qualifier serves to mark a
- method, and the meaning of a qualifier is determined by the way that these
- marks are used by this step of the procedure. If an applicable method has an
- unrecognized qualifier, this step signals an error and does not include that
- method in the effective method.
-
- When standard method combination is used together with qualified methods, the
- effective method is produced as described in section 28.1.7.2.
-
- Another type of method combination can be specified by using the
- :method-combination option of defgeneric or of any of the other forms that
- specify generic function options. In this way this step of the procedure can be
- customized.
-
- New types of method combination can be defined by using the
- define-method-combination macro.
-
- The meta-object level also offers a mechanism for defining new types of method
- combination. The generic function compute-effective-method receives as
- arguments the generic function, the method combination object, and the sorted
- list of applicable methods. It returns the Lisp form that defines the effective
- method. A method for compute-effective-method can be defined directly by using
- defmethod or indirectly by using define-method-combination. A method
- combination object is an object that encapsulates the method combination type
- and options specified by the :method-combination option to forms that specify
- generic function options.
-
- -------------------------------------------------------------------------------
- Implementation note: In the simplest implementation, the generic function would
- compute the effective method each time it was called. In practice, this will be
- too inefficient for some implementations. Instead, these implementations might
- employ a variety of optimizations of the three-step procedure. Some
- illustrative examples of such optimizations are the following:
-
- * Use a hash table keyed by the class of the arguments to store the
- effective method.
-
- * Compile the effective method and save the resulting compiled function in
- a table.
-
- * Recognize the Lisp form as an instance of a pattern of control structure
- and substitute a closure that implements that structure.
-
- * Examine the parameter specializers of all methods for the generic
- function and enumerate all possible effective methods. Combine the
- effective methods, together with code to select from among them, into a
- single function and compile that function. Call that function whenever the
- generic function is called.
-
- -------------------------------------------------------------------------------
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.7.2. Standard Method Combination
-
- [change_begin]
- Standard method combination is supported by the class
- standard-generic-function. It is used if no other type of method combination is
- specified or if the built-in method combination type standard is specified.
-
- Primary methods define the main action of the effective method, while auxiliary
- methods modify that action in one of three ways. A primary method has no method
- qualifiers.
-
- An auxiliary method is a method whose method qualifier is :before, :after, or
- :around. Standard method combination allows no more than one qualifier per
- method; if a method definition specifies more than one qualifier per method, an
- error is signaled.
-
- * A :before method has the keyword :before as its only qualifier. A :before
- method specifies code that is to be run before any primary method.
-
- * An :after method has the keyword :after as its only qualifier. An :after
- method specifies code that is to be run after primary methods.
-
- * An :around method has the keyword :around as its only qualifier. An
- :around method specifies code that is to be run instead of other
- applicable methods but that is able to cause some of them to be run.
-
- The semantics of standard method combination are as follows:
-
- * If there are any :around methods, the most specific :around method is
- called. It supplies the value or values of the generic function.
-
- * Inside the body of an :around method, call-next-method can be used to
- call the next method. When the next method returns, the :around method can
- execute more code, perhaps based on the returned value or values. The
- generic function no-next-method is invoked if call-next-method is used and
- there is no applicable method to call. The function next-method-p may be
- used to determine whether a next method exists.
-
- * If an :around method invokes call-next-method, the next most specific
- :around method is called, if one is applicable. If there are no :around
- methods or if call-next-method is called by the least specific :around
- method, the other methods are called as follows:
-
- o All the :before methods are called, in most-specific-first order.
- Their values are ignored. An error is signaled if call-next-method is
- used in a :before method.
-
- o The most specific primary method is called. Inside the body of a
- primary method, call-next-method may be used to call the next most
- specific primary method. When that method returns, the previous
- primary method can execute more code, perhaps based on the returned
- value or values. The generic function no-next-method is invoked if
- call-next-method is used and there are no more applicable primary
- methods. The function next-method-p may be used to determine whether
- a next method exists. If call-next-method is not used, only the most
- specific primary method is called.
-
- o All the :after methods are called in most-specific-last order. Their
- values are ignored. An error is signaled if call-next-method is used
- in an :after method.
-
- * If no :around methods were invoked, the most specific primary method
- supplies the value or values returned by the generic function. The value
- or values returned by the invocation of call-next-method in the least
- specific :around method are those returned by the most specific primary
- method.
-
- In standard method combination, if there is an applicable method but no
- applicable primary method, an error is signaled.
-
- The :before methods are run in most-specific-first order and the :after methods
- are run in least-specific-first order. The design rationale for this difference
- can be illustrated with an example. Suppose class modifies the behavior of
- its superclass, , by adding :before and :after methods. Whether the behavior
- of the class is defined directly by methods on or is inherited from its
- superclasses does not affect the relative order of invocation of methods on
- instances of the class . Class 's :before method runs before all of class
- 's methods. Class 's :after method runs after all of class 's methods.
-
- By contrast, all :around methods run before any other methods run. Thus a less
- specific :around method runs before a more specific primary method.
-
- If only primary methods are used and if call-next-method is not used, only the
- most specific method is invoked; that is, more specific methods shadow more
- general ones.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.7.3. Declarative Method Combination
-
- [change_begin]
- The macro define-method-combination defines new forms of method combination. It
- provides a mechanism for customizing the production of the effective method.
- The default procedure for producing an effective method is described in section
- 28.1.7.2. There are two forms of define-method-combination. The short form is a
- simple facility; the long form is more powerful and more verbose. The long form
- resembles defmacro in that the body is an expression that computes a Lisp form;
- it provides mechanisms for implementing arbitrary control structures within
- method combination and for arbitrary processing of method qualifiers. The
- syntax and use of both forms of define-method-combination are explained in
- section 28.2.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.7.4. Built-in Method Combination Types
-
- [change_begin]
- The Common Lisp Object System provides a set of built-in method combination
- types. To specify that a generic function is to use one of these method
- combination types, the name of the method combination type is given as the
- argument to the :method-combination option to defgeneric or to the
- :method-combination option to any of the other forms that specify generic
- function options.
-
- The names of the built-in method combination types are +, and, append, list,
- max, min, nconc, or, progn, and standard.
-
- The semantics of the standard built-in method combination type were described
- in section 28.1.7.2. The other built-in method combination types are called
- simple built-in method combination types.
-
- The simple built-in method combination types act as though they were defined by
- the short form of define-method-combination. They recognize two roles for
- methods:
-
- * An :around method has the keyword symbol :around as its sole qualifier.
- The meaning of :around methods is the same as in standard method
- combination. Use of the functions call-next-method and next-method-p is
- supported in :around methods.
-
- * A primary method has the name of the method combination type as its sole
- qualifier. For example, the built-in method combination type and
- recognizes methods whose sole qualifier is and; these are primary methods.
- Use of the functions call-next-method and next-method-p is not supported
- in primary methods.
-
- The semantics of the simple built-in method combination types are as follows:
-
- * If there are any :around methods, the most specific :around method is
- called. It supplies the value or values of the generic function.
-
- * Inside the body of an :around method, the function call-next-method can
- be used to call the next method. The generic function no-next-method is
- invoked if call-next-method is used and there is no applicable method to
- call. The function next-method-p may be used to determine whether a next
- method exists. When the next method returns, the :around method can
- execute more code, perhaps based on the returned value or values.
-
- * If an :around method invokes call-next-method, the next most specific
- :around method is called, if one is applicable. If there are no :around
- methods or if call-next-method is called by the least specific :around
- method, a Lisp form derived from the name of the built-in method
- combination type and from the list of applicable primary methods is
- evaluated to produce the value of the generic function. Suppose the name
- of the method combination type is operator and the call to the generic
- function is of the form
-
- (generic-function ... )
-
- Let be the applicable primary methods in order; then the derived Lisp
- form is
-
- (operator
- ... )
-
- If the expression is evaluated, the method will be applied to the
- arguments . For example, if operator is or, the expression is
- evaluated only if , 1 <= j < i, returned nil.
-
- The default order for the primary methods is :most-specific-first.
- However, the order can be reversed by supplying :most-specific-last as the
- second argument to the :method-combination option.
-
- The simple built-in method combination types require exactly one qualifier per
- method. An error is signaled if there are applicable methods with no qualifiers
- or with qualifiers that are not supported by the method combination type. An
- error is signaled if there are applicable :around methods and no applicable
- primary methods.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.8. Meta-objects
-
- [change_begin]
- The implementation of the Object System manipulates classes, methods, and
- generic functions. The meta-object protocol specifies a set of generic
- functions defined by methods on classes; the behavior of those generic
- functions defines the behavior of the Object System. The instances of the
- classes on which those methods are defined are called meta-objects. Programming
- at the meta-object protocol level involves defining new classes of meta-objects
- along with methods specialized on these classes.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Metaclasses
- * Standard Metaclasses
- * Standard Meta-objects
-
- -------------------------------------------------------------------------------
-
- 28.1.8.1. Metaclasses
-
- [change_begin]
- The metaclass of an object is the class of its class. The metaclass determines
- the representation of instances of its instances and the forms of inheritance
- used by its instances for slot descriptions and method inheritance. The
- metaclass mechanism can be used to provide particular forms of optimization or
- to tailor the Common Lisp Object System for particular uses. The protocol for
- defining metaclasses is discussed in the third part of the CLOS specification,
- The Common Lisp Object System Meta-Object Protocol. [The third part has not yet
- been approved by X3J13 for inclusion in the forthcoming Common Lisp standard
- and is not included in this book.-GLS]
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.8.2. Standard Metaclasses
-
- [change_begin]
- The Common Lisp Object System provides a number of predefined metaclasses.
- These include the classes standard-class, built-in-class, and structure-class:
-
- * The class standard-class is the default class of classes defined by
- defclass.
-
- * The class built-in-class is the class whose instances are classes that
- have special implementations with restricted capabilities. Any class that
- corresponds to a standard Common Lisp type might be an instance of
- built-in-class. The predefined Common Lisp type specifiers that are
- required to have corresponding classes are listed in table 28-1. It is
- implementation-dependent whether each of these classes is implemented as a
- built-in class.
-
- * All classes defined by means of defstruct are instances of
- structure-class.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.8.3. Standard Meta-objects
-
- [change_begin]
- The Object System supplies a standard set of meta-objects, called standard
- meta-objects. These include the class standard-object and instances of the
- classes standard-method, standard-generic-function, and method-combination.
-
- * The class standard-method is the default class of methods that are
- defined by the forms defmethod, defgeneric, generic-function,
- generic-flet, generic-labels, and with-added-methods.
-
- * The class standard-generic-function is the default class of generic
- functions defined by the forms defmethod, defgeneric, generic-function,
- generic-flet, generic-labels, with-added-methods, and defclass.
-
- * The class named standard-object is an instance of the class
- standard-class and is a superclass of every class that is an instance of
- standard-class except itself.
-
- * Every method combination object is an instance of a subclass of the class
- method-combination.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.9. Object Creation and Initialization
-
- [change_begin]
- The generic function make-instance creates and returns a new instance of a
- class. The first argument is a class or the name of a class, and the remaining
- arguments form an initialization argument list.
-
- The initialization of a new instance consists of several distinct steps,
- including the following: combining the explicitly supplied initialization
- arguments with default values for the unsupplied initialization arguments,
- checking the validity of the initialization arguments, allocating storage for
- the instance, filling slots with values, and executing user-supplied methods
- that perform additional initialization. Each step of make-instance is
- implemented by a generic function to provide a mechanism for customizing that
- step. In addition, make-instance is itself a generic function and thus also can
- be customized.
-
- The Object System specifies system-supplied primary methods for each step and
- thus specifies a well-defined standard behavior for the entire initialization
- process. The standard behavior provides four simple mechanisms for controlling
- initialization:
-
- * Declaring a symbol to be an initialization argument for a slot. An
- initialization argument is declared by using the :initarg slot option to
- defclass. This provides a mechanism for supplying a value for a slot in a
- call to make-instance.
-
- * Supplying a default value form for an initialization argument. Default
- value forms for initialization arguments are defined by using the
- :default-initargs class option to defclass. If an initialization argument
- is not explicitly provided as an argument to make-instance, the default
- value form is evaluated in the lexical environment of the defclass form
- that defined it, and the resulting value is used as the value of the
- initialization argument.
-
- * Supplying a default initial value form for a slot. A default initial
- value form for a slot is defined by using the :initform slot option to
- defclass. If no initialization argument associated with that slot is given
- as an argument to make-instance or is defaulted by :default-initargs, this
- default initial value form is evaluated in the lexical environment of the
- defclass form that defined it, and the resulting value is stored in the
- slot. The :initform form for a local slot may be used when creating an
- instance, when updating an instance to conform to a redefined class, or
- when updating an instance to conform to the definition of a different
- class. The :initform form for a shared slot may be used when defining or
- re-defining the class.
-
- * Defining methods for initialize-instance and shared-initialize. The
- slot-filling behavior described above is implemented by a system-supplied
- primary method for initialize-instance which invokes shared-initialize.
- The generic function shared-initialize implements the parts of
- initialization shared by these four situations: when making an instance,
- when re-initializing an instance, when updating an instance to conform to
- a redefined class, and when updating an instance to conform to the
- definition of a different class. The system-supplied primary method for
- shared-initialize directly implements the slot-filling behavior described
- above, and initialize-instance simply invokes shared-initialize.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Initialization Arguments
- * Declaring the Validity of Initialization Arguments
- * Defaulting of Initialization Arguments
- * Rules for Initialization Arguments
- * Shared-Initialize
- * Initialize-Instance
- * Definitions of Make-Instance and Initialize-Instance
-
- -------------------------------------------------------------------------------
-
- 28.1.9.1. Initialization Arguments
-
- [change_begin]
- An initialization argument controls object creation and initialization. It is
- often convenient to use keyword symbols to name initialization arguments, but
- the name of an initialization argument can be any symbol, including nil. An
- initialization argument can be used in two ways: to fill a slot with a value or
- to provide an argument for an initialization method. A single initialization
- argument can be used for both purposes.
-
- An initialization argument list is a list of alternating initialization
- argument names and values. Its structure is identical to a property list and
- also to the portion of an argument list processed for &key parameters. As in
- those lists, if an initialization argument name appears more than once in an
- initialization argument list, the leftmost occurrence supplies the value and
- the remaining occurrences are ignored. The arguments to make-instance (after
- the first argument) form an initialization argument list. Error checking of
- initialization argument names is disabled if the keyword argument pair whose
- keyword is :allow-other-keys and whose value is non-nil appears in the
- initialization argument list.
-
- An initialization argument can be associated with a slot. If the initialization
- argument has a value in the initialization argument list, the value is stored
- into the slot of the newly created object, overriding any :initform form
- associated with the slot. A single initialization argument can initialize more
- than one slot. An initialization argument that initializes a shared slot stores
- its value into the shared slot, replacing any previous value.
-
- An initialization argument can be associated with a method. When an object is
- created and a particular initialization argument is supplied, the generic
- functions initialize-instance, shared-initialize, and allocate-instance are
- called with that initialization argument's name and value as a keyword argument
- pair. If a value for the initialization argument is not supplied in the
- initialization argument list, the method's lambda-list supplies a default
- value.
-
- Initialization arguments are used in four situations: when making an instance,
- when re-initializing an instance, when updating an instance to conform to a
- redefined class, and when updating an instance to conform to the definition of
- a different class.
-
- Because initialization arguments are used to control the creation and
- initialization of an instance of some particular class, we say that an
- initialization argument is ``an initialization argument for'' that class.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.9.2. Declaring the Validity of Initialization Arguments
-
- [change_begin]
- Initialization arguments are checked for validity in each of the four
- situations that use them. An initialization argument may be valid in one
- situation and not another. For example, the system-supplied primary method for
- make-instance defined for the class standard-class checks the validity of its
- initialization arguments and signals an error if an initialization argument is
- supplied that is not declared valid in that situation.
-
- There are two means of declaring initialization arguments valid.
-
- * Initialization arguments that fill slots are declared valid by the
- :initarg slot option to defclass. The :initarg slot option is inherited
- from superclasses. Thus the set of valid initialization arguments that
- fill slots for a class is the union of the initialization arguments that
- fill slots declared valid by that class and its superclasses.
- Initialization arguments that fill slots are valid in all four contexts.
-
- * Initialization arguments that supply arguments to methods are declared
- valid by defining those methods. The keyword name of each keyword
- parameter specified in the method's lambda-list becomes an initialization
- argument for all classes for which the method is applicable. Thus method
- inheritance controls the set of valid initialization arguments that supply
- arguments to methods. The generic functions for which method definitions
- serve to declare initialization arguments valid are as follows:
-
- o Making an instance of a class: allocate-instance,
- initialize-instance, and shared-initialize. Initialization arguments
- declared valid by these methods are valid when making an instance of
- a class.
-
- o Re-initializing an instance: the functions reinitialize-instance and
- shared-initialize. Initialization arguments declared valid by these
- methods are valid when re-initializing an instance.
-
- o Updating an instance to conform to a redefined class:
- update-instance-for-redefined-class and shared-initialize.
- Initialization arguments declared valid by these methods are valid
- when updating an instance to conform to a redefined class.
-
- o Updating an instance to conform to the definition of a different
- class: update-instance-for-different-class and shared-initialize.
- Initialization arguments declared valid by these methods are valid
- when updating an instance to conform to the definition of a different
- class.
-
- The set of valid initialization arguments for a class is the set of valid
- initialization arguments that either fill slots or supply arguments to methods,
- along with the predefined initialization argument :allow-other-keys. The
- default value for :allow-other-keys is nil. The meaning of :allow-other-keys is
- the same here as when it is passed to an ordinary function.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.9.3. Defaulting of Initialization Arguments
-
- [change_begin]
- A default value form can be supplied for an initialization argument by using
- the :default-initargs class option. If an initialization argument is declared
- valid by some particular class, its default value form might be specified by a
- different class. In this case :default-initargs is used to supply a default
- value for an inherited initialization argument.
-
- The :default-initargs option is used only to provide default values for
- initialization arguments; it does not declare a symbol as a valid
- initialization argument name. Furthermore, the :default-initargs option is used
- only to provide default values for initialization arguments when making an
- instance.
-
- The argument to the :default-initargs class option is a list of alternating
- initialization argument names and forms. Each form is the default value form
- for the corresponding initialization argument. The default value form of an
- initialization argument is used and evaluated only if that initialization
- argument does not appear in the arguments to make-instance and is not defaulted
- by a more specific class. The default value form is evaluated in the lexical
- environment of the defclass form that supplied it; the result is used as the
- initialization argument's value.
-
- The initialization arguments supplied to make-instance are combined with
- defaulted initialization arguments to produce a defaulted initialization
- argument list. A defaulted initialization argument list is a list of
- alternating initialization argument names and values in which unsupplied
- initialization arguments are defaulted and in which the explicitly supplied
- initialization arguments appear earlier in the list than the defaulted
- initialization arguments. Defaulted initialization arguments are ordered
- according to the order in the class precedence list of the classes that
- supplied the default values.
-
- There is a distinction between the purposes of the :default-initargs and the
- :initform options with respect to the initialization of slots. The
- :default-initargs class option provides a mechanism for the user to give a
- default value form for an initialization argument without knowing whether the
- initialization argument initializes a slot or is passed to a method. If that
- initialization argument is not explicitly supplied in a call to make-instance,
- the default value form is used, just as if it had been supplied in the call. In
- contrast, the :initform slot option provides a mechanism for the user to give a
- default initial value form for a slot. An :initform form is used to initialize
- a slot only if no initialization argument associated with that slot is given as
- an argument to make-instance or is defaulted by :default-initargs.
-
- The order of evaluation of default value forms for initialization arguments and
- the order of evaluation of :initform forms are undefined. If the order of
- evaluation matters, use initialize-instance or shared-initialize methods.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.9.4. Rules for Initialization Arguments
-
- [change_begin]
- The :initarg slot option may be specified more than once for a given slot. The
- following rules specify when initialization arguments may be multiply defined:
-
- * A given initialization argument can be used to initialize more than one
- slot if the same initialization argument name appears in more than one
- :initarg slot option.
-
- * A given initialization argument name can appear in the lambda-list of
- more than one initialization method.
-
- * A given initialization argument name can appear both in an :initarg slot
- option and in the lambda-list of an initialization method.
-
- If two or more initialization arguments that initialize the same slot are given
- in the arguments to make-instance, the leftmost of these initialization
- arguments in the initialization argument list supplies the value, even if the
- initialization arguments have different names.
-
- If two or more different initialization arguments that initialize the same slot
- have default values and none is given explicitly in the arguments to
- make-instance, the initialization argument that appears in a :default-initargs
- class option in the most specific of the classes supplies the value. If a
- single :default-initargs class option specifies two or more initialization
- arguments that initialize the same slot and none is given explicitly in the
- arguments to make-instance, the leftmost argument in the :default-initargs
- class option supplies the value, and the values of the remaining default value
- forms are ignored.
-
- Initialization arguments given explicitly in the arguments to make-instance
- appear to the left of defaulted initialization arguments. Suppose that the
- classes and supply the values of defaulted initialization arguments for
- different slots, and suppose that is more specific than ; then the
- defaulted initialization argument whose value is supplied by is to the left
- of the defaulted initialization argument whose value is supplied by in the
- defaulted initialization argument list. If a single :default-initargs class
- option supplies the values of initialization arguments for two different slots,
- the initialization argument whose value is specified farther to the left in the
- default-initargs class option appears farther to the left in the defaulted
- initialization argument list.
-
- If a slot has both an :initform form and an :initarg slot option, and the
- initialization argument is defaulted using :default-initargs or is supplied to
- make-instance, the captured :initform form is neither used nor evaluated.
-
- The following is an example of the preceding rules:
-
- (defclass q () ((x :initarg a)))
-
- (defclass r (q) ((x :initarg b))
- (:default-initargs a 1 b 2))
-
- Defaulted Initialization Contents
- Form Argument List of Slot
- =======================================================================
- (make-instance 'r) (a 1 b 2) 1
- (make-instance 'r 'a 3) (a 3 b 2) 3
- (make-instance 'r 'b 4) (b 4 a 1) 4
- (make-instance 'r 'a 1 'a 2) (a 1 a 2 b 2) 1
- =======================================================================
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.9.5. Shared-Initialize
-
- [change_begin]
- The generic function shared-initialize is used to fill the slots of an instance
- using initialization arguments and :initform forms when an instance is created,
- when an instance is re-initialized, when an instance is updated to conform to a
- redefined class, and when an instance is updated to conform to a different
- class. It uses standard method combination. It takes the following arguments:
- the instance to be initialized, a specification of a set of names of slots
- accessible in that instance, and any number of initialization arguments. The
- arguments after the first two must form an initialization argument list.
-
- The second argument to shared-initialize may be one of the following:
-
- * It can be a list of slot names, which specifies the set of those slot
- names.
-
- * It can be nil, which specifies the empty set of slot names.
-
- * It can be the symbol t, which specifies the set of all of the slots.
-
- There is a system-supplied primary method for shared-initialize whose first
- parameter specializer is the class standard-object. This method behaves as
- follows on each slot, whether shared or local:
-
- * If an initialization argument in the initialization argument list
- specifies a value for that slot, that value is stored into the slot, even
- if a value has already been stored in the slot before the method is run.
- The affected slots are independent of which slots are indicated by the
- second argument to shared-initialize.
-
- * Any slots indicated by the second argument that are still unbound at this
- point are initialized according to their :initform forms. For any such
- slot that has an :initform form, that form is evaluated in the lexical
- environment of its defining defclass form and the result is stored into
- the slot. For example, if a :before method stores a value in the slot, the
- :initform form will not be used to supply a value for the slot. If the
- second argument specifies a name that does not correspond to any slots
- accessible in the instance, the results are unspecified.
-
- * The rules mentioned in section 28.1.9.4 are obeyed.
-
- The generic function shared-initialize is called by the system-supplied primary
- methods for the generic functions initialize-instance, reinitialize-instance,
- update-instance-for-different-class, and update-instance-for-redefined-class.
- Thus methods can be written for shared-initialize to specify actions that
- should be taken in all of these contexts.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.9.6. Initialize-Instance
-
- [change_begin]
- The generic function initialize-instance is called by make-instance to
- initialize a newly created instance. It uses standard method combination.
- Methods for initialize-instance can be defined in order to perform any
- initialization that cannot be achieved with the simple slot-filling mechanisms.
-
- During initialization, initialize-instance is invoked after the following
- actions have been taken:
-
- * The defaulted initialization argument list has been computed by combining
- the supplied initialization argument list with any default initialization
- arguments for the class.
-
- * The validity of the defaulted initialization argument list has been
- checked. If any of the initialization arguments has not been declared
- valid, an error is signaled.
-
- * A new instance whose slots are unbound has been created.
-
- The generic function initialize-instance is called with the new instance and
- the defaulted initialization arguments. There is a system-supplied primary
- method for initialize-instance whose parameter specializer is the class
- standard-object. This method calls the generic function shared-initialize to
- fill in the slots according to the initialization arguments and the :initform
- forms for the slots; the generic function shared-initialize is called with the
- following arguments: the instance, t, and the defaulted initialization
- arguments.
-
- Note that initialize-instance provides the defaulted initialization argument
- list in its call to shared-initialize, so the first step performed by the
- system-supplied primary method for shared-initialize takes into account both
- the initialization arguments provided in the call to make-instance and the
- defaulted initialization argument list.
-
- Methods for initialize-instance can be defined to specify actions to be taken
- when an instance is initialized. If only :after methods for initialize-instance
- are defined, they will be run after the system-supplied primary method for
- initialization and therefore they will not interfere with the default behavior
- of initialize-instance.
-
- The Object System provides two functions that are useful in the bodies of
- initialize-instance methods. The function slot-boundp returns a boolean value
- that indicates whether a specified slot has a value; this provides a mechanism
- for writing :after methods for initialize-instance that initialize slots only
- if they have not already been initialized. The function slot-makunbound causes
- the slot to have no value.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.9.7. Definitions of Make-Instance and Initialize-Instance
-
- [change_begin]
- The generic function make-instance behaves as if it were defined as follows,
- except that certain optimizations are permitted:
-
- (defmethod make-instance ((class standard-class) &rest initargs)
- (setq initargs (default-initargs class initargs))
- ...
- (let ((instance (apply #'allocate-instance class initargs)))
- (apply #'initialize-instance instance initargs)
- instance))
- (defmethod make-instance ((class-name symbol) &rest initargs)
- (apply #'make-instance (find-class class-name) initargs))
-
- The elided code in the definition of make-instance checks the supplied
- initialization arguments to determine whether an initialization argument was
- supplied that neither filled a slot nor supplied an argument to an applicable
- method. This check could be implemented using the generic functions
- class-prototype, compute-applicable-methods, function-keywords, and
- class-slot-initargs. See the third part of the Common Lisp Object System
- specification for a description of this initialization argument check. [The
- third part has not yet been approved by X3J13 for inclusion in the forthcoming
- Common Lisp standard and is not included in this book.-GLS]
-
- The generic function initialize-instance behaves as if it were defined as
- follows, except that certain optimizations are permitted:
-
- (defmethod initialize-instance
- ((instance standard-object) &rest initargs)
- (apply #'shared-initialize instance t initargs)))
-
- These procedures can be customized at either the Programmer Interface level,
- the meta-object level, or both.
-
- Customizing at the Programmer Interface level includes using the :initform,
- :initarg, and :default-initargs options to defclass, as well as defining
- methods for make-instance and initialize-instance. It is also possible to
- define methods for shared-initialize, which would be invoked by the generic
- functions reinitialize-instance, update-instance-for-redefined-class,
- update-instance-for-different-class, and initialize-instance. The meta-object
- level supports additional customization by allowing methods to be defined on
- make-instance, default-initargs, and allocate-instance. Parts 2 and 3 of the
- Common Lisp Object System specification document each of these generic
- functions and the system-supplied primary methods. [The third part has not yet
- been approved by X3J13 for inclusion in the forthcoming Common Lisp standard
- and is not included in this book.-GLS]
-
- Implementations are permitted to make certain optimizations to
- initialize-instance and shared-initialize. The description of shared-initialize
- in section 28.2 mentions the possible optimizations.
-
- Because of optimization, the check for valid initialization arguments might not
- be implemented using the generic functions class-prototype,
- compute-applicable-methods, function-keywords, and class-slot-initargs. In
- addition, methods for the generic function default-initargs and the
- system-supplied primary methods for allocate-instance, initialize-instance, and
- shared-initialize might not be called on every call to make-instance or might
- not receive exactly the arguments that would be expected.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.10. Redefining Classes
-
- [change_begin]
- A class that is an instance of standard-class can be redefined if the new class
- will also be an instance of standard-class. Redefining a class modifies the
- existing class object to reflect the new class definition; it does not create a
- new class object for the class. Any method object created by a :reader,
- :writer, or :accessor option specified by the old defclass form is removed from
- the corresponding generic function. Methods specified by the new defclass form
- are added.
-
- When the class C is redefined, changes are propagated to its instances and to
- instances of any of its subclasses. Updating such an instance occurs at an
- implementation-dependent time, but no later than the next time a slot of that
- instance is read or written. Updating an instance does not change its identity
- as defined by the eq function. The updating process may change the slots of
- that particular instance, but it does not create a new instance. Whether
- updating an instance consumes storage is implementation-dependent.
-
- Note that redefining a class may cause slots to be added or deleted. If a class
- is redefined in a way that changes the set of local slots accessible in
- instances, the instances will be updated. It is implementation-dependent
- whether instances are updated if a class is redefined in a way that does not
- change the set of local slots accessible in instances.
-
- The value of a slot that is specified as shared both in the old class and in
- the new class is retained. If such a shared slot was unbound in the old class,
- it will be unbound in the new class. Slots that were local in the old class and
- that are shared in the new class are initialized. Newly added shared slots are
- initialized.
-
- Each newly added shared slot is set to the result of evaluating the captured
- :initform form for the slot that was specified in the defclass form for the new
- class. If there is no :initform form, the slot is unbound.
-
- If a class is redefined in such a way that the set of local slots accessible in
- an instance of the class is changed, a two-step process of updating the
- instances of the class takes place. The process may be explicitly started by
- invoking the generic function make-instances-obsolete. This two-step process
- can happen in other circumstances in some implementations. For example, in some
- implementations this two-step process will be triggered if the order of slots
- in storage is changed.
-
- The first step modifies the structure of the instance by adding new local slots
- and discarding local slots that are not defined in the new version of the
- class. The second step initializes the newly added local slots and performs any
- other user-defined actions. These steps are further specified in the next two
- sections.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Modifying the Structure of Instances
- * Initializing Newly Added Local Slots
- * Customizing Class Redefinition
- * Extensions
-
- -------------------------------------------------------------------------------
-
- 28.1.10.1. Modifying the Structure of Instances
-
- [change_begin]
- The first step modifies the structure of instances of the redefined class to
- conform to its new class definition. Local slots specified by the new class
- definition that are not specified as either local or shared by the old class
- are added, and slots not specified as either local or shared by the new class
- definition that are specified as local by the old class are discarded. The
- names of these added and discarded slots are passed as arguments to
- update-instance-for-redefined-class as described in the next section.
-
- The values of local slots specified by both the new and old classes are
- retained. If such a local slot was unbound, it remains unbound.
-
- The value of a slot that is specified as shared in the old class and as local
- in the new class is retained. If such a shared slot was unbound, the local slot
- will be unbound.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.10.2. Initializing Newly Added Local Slots
-
- [change_begin]
- The second step initializes the newly added local slots and performs any other
- user-defined actions. This step is implemented by the generic function
- update-instance-for-redefined-class, which is called after completion of the
- first step of modifying the structure of the instance.
-
- The generic function update-instance-for-redefined-class takes four required
- arguments: the instance being updated after it has undergone the first step, a
- list of the names of local slots that were added, a list of the names of local
- slots that were discarded, and a property list containing the slot names and
- values of slots that were discarded and had values. Included among the
- discarded slots are slots that were local in the old class and that are shared
- in the new class.
-
- The generic function update-instance-for-redefined-class also takes any number
- of initialization arguments. When it is called by the system to update an
- instance whose class has been redefined, no initialization arguments are
- provided.
-
- There is a system-supplied primary method for the generic function
- update-instance-for-redefined-class whose parameter specializer for its
- instance argument is the class standard-object. First this method checks the
- validity of initialization arguments and signals an error if an initialization
- argument is supplied that is not declared valid (see section 28.1.9.2.) Then it
- calls the generic function shared-initialize with the following arguments: the
- instance, the list of names of the newly added slots, and the initialization
- arguments it received.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.10.3. Customizing Class Redefinition
-
- [change_begin]
- Methods for update-instance-for-redefined-class may be defined to specify
- actions to be taken when an instance is updated. If only :after methods for
- update-instance-for-redefined-class are defined, they will be run after the
- system-supplied primary method for initialization and therefore will not
- interfere with the default behavior of update-instance-for-redefined-class.
- Because no initialization arguments are passed to
- update-instance-for-redefined-class when it is called by the system, the
- :initform forms for slots that are filled by :before methods for
- update-instance-for-redefined-class will not be evaluated by shared-initialize.
-
- Methods for shared-initialize may be defined to customize class redefinition
- (see section 28.1.9.5).
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.10.4. Extensions
-
- [change_begin]
- There are two allowed extensions to class redefinition:
-
- * The Object System may be extended to permit the new class to be an
- instance of a metaclass other than the metaclass of the old class.
-
- * The Object System may be extended to support an updating process when
- either the old or the new class is an instance of a class other than
- standard-class that is not a built-in class.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.11. Changing the Class of an Instance
-
- [change_begin]
- The function change-class can be used to change the class of an instance from
- its current class, , to a different class, ; it changes the structure of
- the instance to conform to the definition of the class .
-
- Note that changing the class of an instance may cause slots to be added or
- deleted.
-
- When change-class is invoked on an instance, a two-step updating process takes
- place. The first step modifies the structure of the instance by adding new
- local slots and discarding local slots that are not specified in the new
- version of the instance. The second step initializes the newly added local
- slots and performs any other user-defined actions. These steps are further
- described in the following two sections.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Modifying the Structure of an Instance
- * Initializing Newly Added Local Slots
- * Customizing the Change of Class of an Instance
-
- -------------------------------------------------------------------------------
-
- 28.1.11.1. Modifying the Structure of an Instance
-
- [change_begin]
- In order to make an instance conform to the class , local slots specified by
- the class that are not specified by the class are added, and local slots
- not specified by the class that are specified by the class are discarded.
-
- The values of local slots specified by both the class and the class are
- retained. If such a local slot was unbound, it remains unbound.
-
- The values of slots specified as shared in the class and as local in the
- class are retained.
-
- This first step of the update does not affect the values of any shared slots.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.11.2. Initializing Newly Added Local Slots
-
- [change_begin]
- The second step of the update initializes the newly added slots and performs
- any other user-defined actions. This step is implemented by the generic
- function update-instance-for-different-class. The generic function
- update-instance-for-different-class is invoked by change-class after the first
- step of the update has been completed.
-
- The generic function update-instance-for-different-class is invoked on two
- arguments computed by change-class. The first argument passed is a copy of the
- instance being updated and is an instance of the class ; this copy has
- dynamic extent within the generic function change-class. The second argument is
- the instance as updated so far by change-class and is an instance of the class
- .
-
- The generic function update-instance-for-different-class also takes any number
- of initialization arguments. When it is called by change-class, no
- initialization arguments are provided.
-
- There is a system-supplied primary method for the generic function
- update-instance-for-different-class that has two parameter specializers, each
- of which is the class standard-object. First this method checks the validity of
- initialization arguments and signals an error if an initialization argument is
- supplied that is not declared valid (see section 28.1.9.2). Then it calls the
- generic function shared-initialize with the following arguments: the instance,
- a list of names of the newly added slots, and the initialization arguments it
- received.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.11.3. Customizing the Change of Class of an Instance
-
- [change_begin]
- Methods for update-instance-for-different-class may be defined to specify
- actions to be taken when an instance is updated. If only :after methods for
- update-instance-for-different-class are defined, they will be run after the
- system-supplied primary method for initialization and will not interfere with
- the default behavior of update-instance-for-different-class. Because no
- initialization arguments are passed to update-instance-for-different-class when
- it is called by change-class, the :initform forms for slots that are filled by
- :before methods for update-instance-for-different-class will not be evaluated
- by shared-initialize.
-
- Methods for shared-initialize may be defined to customize class redefinition
- (see section 28.1.9.5).
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 28.1.12. Reinitializing an Instance
-
- [change_begin]
- The generic function reinitialize-instance may be used to change the values of
- slots according to initialization arguments.
-
- The process of reinitialization changes the values of some slots and performs
- any user-defined actions.
-
- Reinitialization does not modify the structure of an instance to add or delete
- slots, and it does not use any :initform forms to initialize slots.
-
- The generic function reinitialize-instance may be called directly. It takes one
- required argument, the instance. It also takes any number of initialization
- arguments to be used by methods for reinitialize-instance or for
- shared-initialize. The arguments after the required instance must form an
- initialization argument list.
-
- There is a system-supplied primary method for reinitialize-instance whose
- parameter specializer is the class standard-object. First this method checks
- the validity of initialization arguments and signals an error if an
- initialization argument is supplied that is not declared valid (see section
- 28.1.9.2). Then it calls the generic function shared-initialize with the
- following arguments: the instance, nil, and the initialization arguments it
- received.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Customizing Reinitialization
-
- -------------------------------------------------------------------------------
-
- 28.1.12.1. Customizing Reinitialization
-
- [change_begin]
- Methods for the generic function reinitialize-instance may be defined to
- specify actions to be taken when an instance is updated. If only :after methods
- for reinitialize-instance are defined, they will be run after the
- system-supplied primary method for initialization and therefore will not
- interfere with the default behavior of reinitialize-instance.
-
- Methods for shared-initialize may be defined to customize class redefinition
- (see section 28.1.9.5).
- [change_end]
-
- -------------------------------------------------------------------------------
-
-
- 28.2. Functions in the Programmer Interface
-
- [change_begin]
- This section describes the functions, macros, special forms, and generic
- functions provided by the Common Lisp Object System Programmer Interface. The
- Programmer Interface comprises the functions and macros that are sufficient for
- writing most object-oriented programs.
-
- This section is reference material that requires an understanding of the basic
- concepts of the Common Lisp Object System. The functions are arranged in
- alphabetical order for convenient reference.
-
- The description of each function, macro, special form, and generic function
- includes its purpose, its syntax, the semantics of its arguments and returned
- values, and often an example and cross-references to related functions.
-
- The syntax description for a function, macro, or special form describes its
- parameters. The description of a generic function includes descriptions of the
- methods that are defined on that generic function by the Common Lisp Object
- System. A method signature is used to describe the parameters and parameter
- specializers for each method.
-
- The following is an example of the format for the syntax description of a
- generic function with the method signature for one primary method:
-
- [Generic function]
- f x y &optional z &key :k
- [Primary method]
- f (x class) (y t) &optional z &key :k
-
- This description indicates that the generic function f has two required
- parameters, x and y. In addition, there is an optional parameter z and a
- keyword parameter :k.
-
- The method signature indicates that this method on the generic function f has
- two required parameters, x, which must be an instance of the class class, and
- y, which can be any object. In addition, there is an optional parameter z and a
- keyword parameter :k. The signature also indicates that this method on f is a
- primary method and has no qualifiers.
-
- The syntax description for a generic function describes the lambda-list of the
- generic function itself, while the method signatures describe the lambda-lists
- of the defined methods.
-
- The generic functions described in this book are all standard generic
- functions. They all use standard method combination.
-
- Any implementation of the Common Lisp Object System is allowed to provide
- additional methods on the generic functions described here.
-
- It is useful to categorize the functions and macros according to their role in
- this standard:
-
- * Tools used for simple object-oriented programming
-
- These tools allow for defining new classes, methods, and generic functions
- and for making instances. Some tools used within method bodies are also
- listed here. Some of the macros listed here have a corresponding function
- that performs the same task at a lower level of abstraction.
-
- call-next-method initialize-instance
- change-class make-instance
- defclass next-method-p
- defgeneric slot-boundp
- defmethod slot-value
- generic-flet with-accessors
- generic-function with-added-methods
- generic-labels with-slots
-
- * Functions underlying the commonly used macros
-
- add-method reinitialize-instance
- class-name remove-method
- compute-applicable-methods shared-initialize
- ensure-generic-function slot-exists-p
- find-class slot-makunbound
- find-method slot-missing
- function-keywords slot-unbound
- make-instances-obsolete update-instance-for-different-class
- no-applicable-method update-instance-for-redefined-class
- no-next-method
-
- * Tools for declarative method combination
-
- call-method method-combination-error
- define-method-combination method-qualifiers
- invalid-method-error
-
- * General Common Lisp support tools
-
- class-of print-object
- documentation symbol-macrolet
-
- [Note that describe appeared in this list in the original CLOS proposal
- [5,7], but X3J13 voted in March 1989 (DESCRIBE-UNDERSPECIFIED) not to
- make describe a generic function after all (see describe-object).-GLS]
-
- [At this point the original CLOS report contained a description of the [[ and
- ]] notation; that description is omitted here. I have adopted the notation for
- use throughout this book. It is described in section 1.2.5.-GLS]
-
- [Generic function]
- add-method generic-function method
- [Primary method]
-
- add-method
- (generic-function standard-generic-function) (method method)
-
- The generic function add-method adds a method to a generic function. It
- destructively modifies the generic function and returns the modified generic
- function as its result.
-
- The generic-function argument is a generic function object.
-
- The method argument is a method object. The lambda-list of the method function
- must be congruent with the lambda-list of the generic function, or an error is
- signaled.
-
- The modified generic function is returned. The result of add-method is eq to
- the generic-function argument.
-
- If the given method agrees with an existing method of the generic function on
- parameter specializers and qualifiers, the existing method is replaced. See
- section 28.1.6.3 for a definition of agreement in this context.
-
- If the method object is a method object of another generic function, an error
- is signaled.
-
- See section 28.1.6.3 as well as defmethod, defgeneric, find-method, and
- remove-method.
-
- [Macro]
- call-method method next-method-list
-
- The macro call-method is used in method combination. This macro hides the
- implementation-dependent details of how methods are called. It can be used only
- within an effective method form, for the name call-method is defined only
- within the lexical scope of such a form.
-
- The macro call-method invokes the specified method, supplying it with arguments
- and with definitions for call-next-method and for next-method-p. The arguments
- are the arguments that were supplied to the effective method form containing
- the invocation of call-method. The definitions of call-next-method and
- next-method-p rely on the list of method objects given as the second argument
- to call-method.
-
- The call-next-method function available to the method that is the first subform
- will call the first method in the list that is the second subform. The
- call-next-method function available in that method, in turn, will call the
- second method in the list that is the second subform, and so on, until the list
- of next methods is exhausted.
-
- The method argument is a method object; the next-method-list argument is a list
- of method objects.
-
- A list whose first element is the symbol make-method and whose second element
- is a Lisp form can be used instead of a method object as the first subform of
- call-method or as an element of the second subform of call-method. Such a list
- specifies a method object whose method function has a body that is the given
- form.
-
- The result of call-method is the value or values returned by the method
- invocation.
-
- See call-next-method, define-method-combination, and next-method-p.
-
- [Function]
- call-next-method &rest args
-
- The function call-next-method can be used within the body of a method defined
- by a method-defining form to call the next method.
-
- The function call-next-method returns the value or values returned by the
- method it calls. If there is no next method, the generic function
- no-next-method is called.
-
- The type of method combination used determines which methods can invoke
- call-next-method. The standard method combination type allows call-next-method
- to be used within primary methods and :around methods.
-
- The standard method combination type defines the next method according to the
- following rules:
-
- * If call-next-method is used in an :around method, the next method is the
- next most specific :around method, if one is applicable.
-
- * If there are no :around methods at all or if call-next-method is called
- by the least specific :around method, other methods are called as follows:
-
- o All the :before methods are called, in most-specific-first order.
- The function call-next-method cannot be used in :before methods.
-
- o The most specific primary method is called. Inside the body of a
- primary method, call-next-method may be used to pass control to the
- next most specific primary method. The generic function
- no-next-method is called if call-next-method is used and there are no
- more primary methods.
-
- o All the :after methods are called in most-specific-last order. The
- function call-next-method cannot be used in :after methods.
-
- For further discussion of the use of call-next-method, see sections 28.1.7.2
- and 28.1.7.4.
-
- When call-next-method is called with no arguments, it passes the current
- method's original arguments to the next method. Neither argument defaulting,
- nor using setq, nor rebinding variables with the same names as parameters of
- the method affects the values call-next-method passes to the method it calls.
-
- When call-next-method is called with arguments, the next method is called with
- those arguments. When providing arguments to call-next-method, the following
- rule must be satisfied or an error is signaled: The ordered set of methods
- applicable for a changed set of arguments for call-next-method must be the same
- as the ordered set of applicable methods for the original arguments to the
- generic function. Optimizations of the error checking are possible, but they
- must not change the semantics of call-next-method.
-
- If call-next-method is called with arguments but omits optional arguments, the
- next method called defaults those arguments.
-
- The function call-next-method returns the value or values returned by the
- method it calls.
-
- Further computation is possible after call-next-method returns.
-
- The definition of the function call-next-method has lexical scope (for it is
- defined only within the body of a method defined by a method-defining form) and
- indefinite extent.
-
- For generic functions using a type of method combination defined by the short
- form of define-method-combination, call-next-method can be used in :around
- methods only.
-
- The function next-method-p can be used to test whether or not there is a next
- method.
-
- If call-next-method is used in methods that do not support it, an error is
- signaled.
-
- See sections 28.1.7, 28.1.7.2, and 28.1.7.4 as well as the functions
- define-method-combination, next-method-p, and no-next-method.
-
- [Generic function]
-
- change-class instance new-class
-
- [Primary method]
-
- change-class (instance standard-object)
- (new-class standard-class)
- change-class (instance t)
- (new-class symbol)
-
- The generic function change-class changes the class of an instance to a new
- class. It destructively modifies and returns the instance.
-
- If in the old class there is any slot of the same name as a local slot in the
- new class, the value of that slot is retained. This means that if the slot has
- a value, the value returned by slot-value after change-class is invoked is eql
- to the value returned by slot-value before change-class is invoked. Similarly,
- if the slot was unbound, it remains unbound. The other slots are initialized as
- described in section 28.1.11.
-
- The instance argument is a Lisp object.
-
- The new-class argument is a class object or a symbol that names a class.
-
- If the second of the preceding methods is selected, that method invokes
- change-class on instance and (find-class new-class).
-
- The modified instance is returned. The result of change-class is eq to the
- instance argument.
-
- Examples:
-
- (defclass position () ())
-
- (defclass x-y-position (position)
- ((x :initform 0 :initarg :x)
- (y :initform 0 :initarg :y)))
-
- (defclass rho-theta-position (position)
- ((rho :initform 0)
- (theta :initform 0)))
-
- (defmethod update-instance-for-different-class :before
- ((old x-y-position)
- (new rho-theta-position)
- &key)
- ;; Copy the position information from old to new to make new
- ;; be a rho-theta-position at the same position as old.
- (let ((x (slot-value old 'x))
- (y (slot-value old 'y)))
- (setf (slot-value new 'rho) (sqrt (+ (* x x) (* y y)))
- (slot-value new 'theta) (atan y x))))
-
- ;;; At this point an instance of the class x-y-position can be
- ;;; changed to be an instance of the class rho-theta-position
- ;;; using change-class:
-
- (setq p1 (make-instance 'x-y-position :x 2 :y 0))
-
- (change-class p1 'rho-theta-position)
-
- ;;; The result is that the instance bound to p1 is now
- ;;; an instance of the class rho-theta-position.
- ;;; The update-instance-for-different-class method
- ;;; performed the initialization of the rho and theta
- ;;; slots based on the values of the x and y slots,
- ;;; which were maintained by the old instance.
-
- After completing all other actions, change-class invokes the generic function
- update-instance-for-different-class. The generic function
- update-instance-for-different-class can be used to assign values to slots in
- the transformed instance.
-
- The generic function change-class has several semantic difficulties. First, it
- performs a destructive operation that can be invoked within a method on an
- instance that was used to select that method. When multiple methods are
- involved because methods are being combined, the methods currently executing or
- about to be executed may no longer be applicable. Second, some implementations
- might use compiler optimizations of slot access, and when the class of an
- instance is changed the assumptions the compiler made might be violated. This
- implies that a programmer must not use change-class inside a method if any
- methods for that generic function access any slots, or the results are
- undefined.
-
- See section 28.1.11 as well as update-instance-for-different-class.
-
- [Generic function]
- class-name class
-
- [Primary method]
- class-name (class class)
-
- The generic function class-name takes a class object and returns its name. The
- class argument is a class object. The new-value argument is any object. The
- name of the given class is returned.
-
- The name of an anonymous class is nil.
-
- If S is a symbol such that S =(class-name C) and C = (find-class S), then S is
- the proper name of C (see section 28.1.2).
-
- See also section 28.1.2 and find-class.
-
- [Generic function]
- (setf class-name) new-value class
-
- [Primary method]
- (setf class-name) new-value (class class)
-
- The generic function (setf class-name) takes a class object and sets its name.
- The class argument is a class object. The new-value argument is any object.
-
- [Function]
- class-of object
-
- The function class-of returns the class of which the given object is an
- instance. The argument to class-of may be any Common Lisp object. The function
- class-of returns the class of which the argument is an instance.
-
- [Function]
- compute-applicable-methods generic-function function-arguments
-
- Given a generic function and a set of arguments, the function
- compute-applicable-methods returns the set of methods that are applicable for
- those arguments.
-
- The methods are sorted according to precedence order. See section 28.1.7.
-
- The generic-function argument must be a generic function object. The
- function-arguments argument is a list of the arguments to that generic
- function. The result is a list of the applicable methods in order of
- precedence. See section 28.1.7.
-
- [Macro]
-
- defclass class-name ({superclass-name}*)
- ({slot-specifier}*) [[?class-option]]
-
- class-name ::= symbol
- superclass-name ::= symbol
- slot-specifier ::= slot-name | (slot-name [[?slot-option]])
- slot-name ::= symbol
- slot-option ::= {:reader reader-function-name}*
- | {:writer writer-function-name}*
- | {:accessor reader-function-name}*
- | {:allocation allocation-type}*
- | {:initarg initarg-name}*
- | {:initform form}*
- | {:type type-specifier}*
- | {:documentation string}*
-
- reader-function-name ::= symbol
- writer-function-name ::= function-name/
- function-name ::= {symbol | (setf symbol)}
- initarg-name ::= symbol
- allocation-type ::= :instance | :class
- class-option ::= (:default-initargs initarg-list)
- | (:documentation string)
- | (:metaclass class-name)
- initarg-list ::= {initarg-name default-initial-value-form}*
-
- The macro defclass defines a new named class. It returns the new class object
- as its result.
-
- The syntax of defclass provides options for specifying initialization arguments
- for slots, for specifying default initialization values for slots, and for
- requesting that methods on specified generic functions be automatically
- generated for reading and writing the values of slots. No reader or writer
- functions are defined by default; their generation must be explicitly
- requested.
-
- Defining a new class also causes a type of the same name to be defined. The
- predicate (typep object class-name) returns true if the class of the given
- object is class-name itself or a subclass of the class class-name. A class
- object can be used as a type specifier. Thus (typep object class) returns true
- if the class of the object is class itself or a subclass of class.
-
- The class-name argument is a non-nil symbol. It becomes the proper name of the
- new class. If a class with the same proper name already exists and that class
- is an instance of standard-class, and if the defclass form for the definition
- of the new class specifies a class of class standard-class, the definition of
- the existing class is replaced.
-
- Each superclass-name argument is a non-nil symbol that specifies a direct
- superclass of the new class. The new class will inherit slots and methods from
- each of its direct superclasses, from their direct superclasses, and so on. See
- section 28.1.3 for a discussion of how slots and methods are inherited.
-
- Each slot-specifier argument is the name of the slot or a list consisting of
- the slot name followed by zero or more slot options. The slot-name argument is
- a symbol that is syntactically valid for use as a variable name. If there are
- any duplicate slot names, an error is signaled.
-
- The following slot options are available:
-
- * The :reader slot option specifies that an unqualified method is to be
- defined on the generic function named reader-function-name to read the
- value of the given slot. The reader-function-name argument is a non-nil
- symbol. The :reader slot option may be specified more than once for a
- given slot.
-
- * The :writer slot option specifies that an unqualified method is to be
- defined on the generic function named writer-function-name to write the
- value of the slot. The writer-function-name argument is a function-name.
- The :writer slot option may be specified more than once for a given slot.
-
- * The :accessor slot option specifies that an unqualified method is to be
- defined on the generic function named reader-function-name to read the
- value of the given slot and that an unqualified method is to be defined on
- the generic function named (setf reader-function-name) to be used with
- setf to modify the value of the slot. The reader-function-name argument is
- a non-nil symbol. The :accessor slot option may be specified more than
- once for a given slot.
-
- * The :allocation slot option is used to specify where storage is to be
- allocated for the given slot. Storage for a slot may be located in each
- instance or in the class object itself, for example. The value of the
- allocation-type argument can be either the keyword :instance or the
- keyword :class. The :allocation slot option may be specified at most once
- for a given slot. If the :allocation slot option is not specified, the
- effect is the same as specifying :allocation :instance.
-
- o If allocation-type is :instance, a local slot of the given name is
- allocated in each instance of the class.
-
- o If allocation-type is :class, a shared slot of the given name is
- allocated. The value of the slot is shared by all instances of the
- class. If a class C defines such a shared slot, any subclass C of C
- will share this single slot unless the defclass form for C specifies
- a slot of the same name or there is a superclass of C that precedes C
- in the class precedence list of C and that defines a slot of the same
- name.
-
- * The :initform slot option is used to provide a default initial value form
- to be used in the initialization of the slot. The :initform slot option
- may be specified at most once for a given slot. This form is evaluated
- every time it is used to initialize the slot. The lexical environment in
- which this form is evaluated is the lexical environment in which the
- defclass form was evaluated. Note that the lexical environment refers both
- to variables and to functions. For local slots, the dynamic environment is
- the dynamic environment in which make-instance was called; for shared
- slots, the dynamic environment is the dynamic environment in which the
- defclass form was evaluated. See section 28.1.9.
-
- No implementation is permitted to extend the syntax of defclass to allow
- (slot-name form) as an abbreviation for (slot-name :initform form).
-
- * The :initarg slot option declares an initialization argument named
- initarg-name and specifies that this initialization argument initializes
- the given slot. If the initialization argument has a value in the call to
- initialize-instance, the value will be stored into the given slot, and the
- slot's :initform slot option, if any, is not evaluated. If none of the
- initialization arguments specified for a given slot has a value, the slot
- is initialized according to the :initform slot option, if specified. The
- :initarg slot option can be specified more than once for a given slot. The
- initarg-name argument can be any symbol.
-
- * The :type slot option specifies that the contents of the slot will always
- be of the specified data type. It effectively declares the result type of
- the reader generic function when applied to an object of this class. The
- result of attempting to store in a slot a value that does not satisfy the
- type of the slot is undefined. The :type slot option may be specified at
- most once for a given slot. The :type slot option is further discussed in
- section 28.1.3.2.
-
- * The :documentation slot option provides a documentation string for the
- slot.
-
- Each class option is an option that refers to the class as a whole or to all
- class slots. The following class options are available:
-
- * The :default-initargs class option is followed by a list of alternating
- initialization argument names and default initial value forms. If any of
- these initialization arguments does not appear in the initialization
- argument list supplied to make-instance, the corresponding default initial
- value form is evaluated, and the initialization argument name and the
- form's value are added to the end of the initialization argument list
- before the instance is created (see section 28.1.9). The default initial
- value form is evaluated each time it is used. The lexical environment in
- which this form is evaluated is the lexical environment in which the
- defclass form was evaluated. The dynamic environment is the dynamic
- environment in which make-instance was called. If an initialization
- argument name appears more than once in a :default-initargs class option,
- an error is signaled. The :default-initargs class option may be specified
- at most once.
-
- * The :documentation class option causes a documentation string to be
- attached to the class name. The documentation type for this string is
- type. The form (documentation class-name 'type) may be used to retrieve
- the documentation string. The :documentation class option may be specified
- at most once.
-
- * The :metaclass class option is used to specify that instances of the
- class being defined are to have a different metaclass than the default
- provided by the system (the class standard-class). The class-name argument
- is the name of the desired metaclass. The :metaclass class option may be
- specified at most once.
-
- The new class object is returned as the result.
-
- If a class with the same proper name already exists and that class is an
- instance of standard-class, and if the defclass form for the definition of the
- new class specifies a class of class standard-class, the existing class is
- redefined, and instances of it (and its subclasses) are updated to the new
- definition at the time that they are next accessed (see section 28.1.10).
-
- Note the following rules of defclass for standard classes:
-
- * It is not required that the superclasses of a class be defined before the
- defclass form for that class is evaluated.
-
- * All the superclasses of a class must be defined before an instance of the
- class can be made.
-
- * A class must be defined before it can be used as a parameter specializer
- in a defmethod form.
-
- The Object System may be extended to cover situations where these rules are not
- obeyed.
-
- Some slot options are inherited by a class from its superclasses, and some can
- be shadowed or altered by providing a local slot description. No class options
- except :default-initargs are inherited. For a detailed description of how slots
- and slot options are inherited, see section 28.1.3.2.
-
- The options to defclass can be extended. An implementation must signal an error
- if it observes a class option or a slot option that is not implemented locally.
-
- It is valid to specify more than one reader, writer, accessor, or
- initialization argument for a slot. No other slot option may appear more than
- once in a single slot description, or an error is signaled.
-
- If no reader, writer, or accessor is specified for a slot, the slot can be
- accessed only by the function slot-value.
-
- See sections 28.1.2, 28.1.3, 28.1.10, 28.1.5, 28.1.9 as well as slot-value,
- make-instance, and initialize-instance.
-
- [Macro]
-
- defgeneric function-name lambda-list
- [[?option | {method-description}*]]
-
- function-name ::= {symbol | (setf symbol)}
- lambda-list ::= ({var}*
- [&optional {var | (var)}*]
- [&rest var]
- [&key {keyword-parameter}* [&allow-other-keys]])
- keyword-parameter ::= var | ({var | (keyword var)})
- option ::= (:argument-precedence-order {parameter-name}+)
- | (declare {declaration}+)
- | (:documentation string)
- | (:method-combination symbol {arg}*)
- | (:generic-function-class class-name)
- | (:method-class class-name)
- method-description ::= (:method {method-qualifier}*
- specialized-lambda-list
- [[ {declaration}* | documentation ]]
- {form}*)
- method-qualifier ::= non-nil-atom
- specialized-lambda-list ::=
- ({var | (var parameter-specializer-name)}*
- [&optional {var | (var [initform [supplied-p-parameter]])}*]
- [&rest var]
- [&key {specialized-keyword-parameter}* [&allow-other-keys]]
- [&aux {var | (var [initform])}*])
- specialized-keyword-parameter ::=
- var | ({var | (keyword var)} [initform [supplied-p-parameter]])
- parameter-specializer-name ::= symbol | (eql eql-specializer-form)
-
- The macro defgeneric is used to define a generic function or to specify options
- and declarations that pertain to a generic function as a whole.
-
- If (fboundp function-name) is nil, a new generic function is created. If
- (fdefinition function-specifier) is a generic function, that generic function
- is modified. If function-name/ names a non-generic function, a macro, or a
- special form, an error is signaled.
-
- [X3J13 voted in March 1989 (FUNCTION-NAME) to use fdefinition in the previous
- paragraph, as shown, rather than symbol-function, as it appeared in the
- original report on CLOS [5,7]. The vote also changed all occurrences of
- function-specifier in the original report to function-name; this change is
- reflected here.-GLS]
-
- Each method-description defines a method on the generic function. The
- lambda-list of each method must be congruent with the lambda-list specified by
- the lambda-list option. If this condition does not hold, an error is signaled.
- See section 28.1.6.4 for a definition of congruence in this context.
-
- The macro defgeneric returns the generic function object as its result.
-
- The function-name argument is a non-nil symbol or a list of the form (setf
- symbol).
-
- The lambda-list argument is an ordinary function lambda-list with the following
- exceptions:
-
- * The use of &aux is not allowed.
-
- * Optional and keyword arguments may not have default initial value forms
- nor use supplied-p parameters. The generic function passes to the method
- all the argument values passed to it, and only those; default values are
- not supported. Note that optional and keyword arguments in method
- definitions, however, can have default initial value forms and can use
- supplied-p parameters.
-
- The following options are provided. A given option may occur only once, or an
- error is signaled.
-
- * The :argument-precedence-order option is used to specify the order in
- which the required arguments in a call to the generic function are tested
- for specificity when selecting a particular method. Each required
- argument, as specified in the lambda-list argument, must be included
- exactly once as a parameter-name so that the full and unambiguous
- precedence order is supplied. If this condition is not met, an error is
- signaled.
-
- * The declare option is used to specify declarations that pertain to the
- generic function. The following standard Common Lisp declaration is
- allowed:
-
- o An optimize declaration specifies whether method selection should be
- optimized for speed or space, but it has no effect on methods. To
- control how a method is optimized, an optimize declaration must be
- placed directly in the defmethod form or method description. The
- optimization qualities speed and space are the only qualities this
- standard requires, but an implementation can extend the Common Lisp
- Object System to recognize other qualities. A simple implementation
- that has only one method selection technique and ignores the optimize
- declaration is valid.
-
- The special, ftype, function, inline, notinline, and declaration
- declarations are not permitted. Individual implementations can extend the
- declare option to support additional declarations. If an implementation
- notices a declaration that it does not support and that has not been
- proclaimed as a non-standard declaration name in a declaration
- proclamation, it should issue a warning.
-
- * The :documentation argument associates a documentation string with the
- generic function. The documentation type for this string is function. The
- form (documentation function-name/ 'function) may be used to retrieve this
- string.
-
- * The :generic-function-class option may be used to specify that the
- generic function is to have a different class than the default provided by
- the system (the class standard-generic-function). The class-name argument
- is the name of a class that can be the class of a generic function. If
- function-name specifies an existing generic function that has a different
- value for the :generic-function-class argument and the new generic
- function class is compatible with the old, change-class is called to
- change the class of the generic function; otherwise an error is signaled.
-
- * The :method-class option is used to specify that all methods on this
- generic function are to have a different class from the default provided
- by the system (the class standard-method). The class-name argument is the
- name of a class that is capable of being the class of a method.
-
- * The :method-combination option is followed by a symbol that names a type
- of method combination. The arguments (if any) that follow that symbol
- depend on the type of method combination. Note that the standard method
- combination type does not support any arguments. However, all types of
- method combination defined by the short form of define-method-combination
- accept an optional argument named order, defaulting to
- :most-specific-first, where a value of :most-specific-last reverses the
- order of the primary methods without affecting the order of the auxiliary
- methods.
-
- The method-description arguments define methods that will be associated with
- the generic function. The method-qualifier and specialized-lambda-list
- arguments in a method description are the same as for defmethod.
-
- The form arguments specify the method body. The body of the method is enclosed
- in an implicit block. If function-name is a symbol, this block bears the same
- name as the generic function. If function-name is a list of the form (setf
- symbol), the name of the block is symbol.
-
- The generic function object is returned as the result.
-
- The effect of the defgeneric macro is as if the following three steps were
- performed: first, methods defined by previous defgeneric forms are removed;
- second, ensure-generic-function is called; and finally, methods specified by
- the current defgeneric form are added to the generic function.
-
- If no method descriptions are specified and a generic function of the same name
- does not already exist, a generic function with no methods is created.
-
- The lambda-list argument of defgeneric specifies the shape of lambda-lists for
- the methods on this generic function. All methods on the resulting generic
- function must have lambda-lists that are congruent with this shape. If a
- defgeneric form is evaluated and some methods for that generic function have
- lambda-lists that are not congruent with that given in the defgeneric form, an
- error is signaled. For further details on method congruence, see section
- 28.1.6.4.
-
- Implementations can extend defgeneric to include other options. It is required
- that an implementation signal an error if it observes an option that is not
- implemented locally.
-
- See section 28.1.6.4 as well as defmethod, ensure-generic-function, and
- generic-function.
-
- [Macro]
-
- define-method-combination name [[?short-form-option]]
- define-method-combination name lambda-list
- ({method-group-specifier}*)
- [(:arguments . lambda-list)]
- [(:generic-function generic-fn-symbol)]
- [[{declaration}* | doc-string]]
- {form}*
-
- short-form-option ::= :documentation string
- | :identity-with-one-argument boolean
- | :operator operator
- method-group-specifier ::= (variable {{qualifier-pattern}+ | predicate}
- [[?long-form-option]])
- long-form-option ::= :description format-string
- | :order order
- | :required boolean
-
- The macro define-method-combination is used to define new types of method
- combination.
-
- There are two forms of define-method-combination. The short form is a simple
- facility for the cases that are expected to be most commonly needed. The long
- form is more powerful but more verbose. It resembles defmacro in that the body
- is an expression, usually using backquote, that computes a Lisp form. Thus
- arbitrary control structures can be implemented. The long form also allows
- arbitrary processing of method qualifiers.
-
- In both the short and long forms, name is a symbol. By convention, non-keyword,
- non-nil symbols are usually used.
-
- The short-form syntax of define-method-combination is recognized when the
- second subform is a non-nil symbol or is not present. When the short form is
- used, name is defined as a type of method combination that produces a Lisp form
- (operator method-call method-call ... ). The operator is a symbol that can be
- the name of a function, macro, or special form. The operator can be specified
- by a keyword option; it defaults to name.
-
- Keyword options for the short form are the following:
-
- * The :documentation option is used to document the method-combination
- type.
-
- * The :identity-with-one-argument option enables an optimization when
- boolean is true (the default is false). If there is exactly one applicable
- method and it is a primary method, that method serves as the effective
- method and operator is not called. This optimization avoids the need to
- create a new effective method and avoids the overhead of a function call.
- This option is designed to be used with operators such as progn, and, +,
- and max.
-
- * The :operator option specifies the name of the operator. The operator
- argument is a symbol that can be the name of a function, macro, or special
- form. By convention, name and operator are often the same symbol. This is
- the default, but it is not required.
-
- None of the subforms is evaluated.
-
- These types of method combination require exactly one qualifier per method. An
- error is signaled if there are applicable methods with no qualifiers or with
- qualifiers that are not supported by the method combination type.
-
- A method combination procedure defined in this way recognizes two roles for
- methods. A method whose one qualifier is the symbol naming this type of method
- combination is defined to be a primary method. At least one primary method must
- be applicable or an error is signaled. A method with :around as its one
- qualifier is an auxiliary method that behaves the same as an :around method in
- standard method combination. The function call-next-method can be used only in
- :around methods; it cannot be used in primary methods defined by the short form
- of the define-method-combination macro.
-
- A method combination procedure defined in this way accepts an optional argument
- named order, which defaults to :most-specific-first. A value of
- :most-specific-last reverses the order of the primary methods without affecting
- the order of the auxiliary methods.
-
- The short form automatically includes error checking and support for :around
- methods.
-
- For a discussion of built-in method combination types, see section 28.1.7.4.
-
- The long-form syntax of define-method-combination is recognized when the second
- subform is a list.
-
- The lambda-list argument is an ordinary lambda-list. It receives any arguments
- provided after the name of the method combination type in the
- :method-combination option to defgeneric.
-
- A list of method group specifiers follows. Each specifier selects a subset of
- the applicable methods to play a particular role, either by matching their
- qualifiers against some patterns or by testing their qualifiers with a
- predicate. These method group specifiers define all method qualifiers that can
- be used with this type of method combination. If an applicable method does not
- fall into any method group, the system signals the error that the method is
- invalid for the kind of method combination in use.
-
- Each method group specifier names a variable. During the execution of the forms
- in the body of define-method-combination, this variable is bound to a list of
- the methods in the method group. The methods in this list occur in
- most-specific-first order.
-
- A qualifier pattern is a list or the symbol *. A method matches a qualifier
- pattern if the method's list of qualifiers is equal to the qualifier pattern
- (except that the symbol * in a qualifier pattern matches anything). Thus a
- qualifier pattern can be one of the following: the empty list (), which matches
- unqualified methods; the symbol *, which matches all methods; a true list,
- which matches methods with the same number of qualifiers as the length of the
- list when each qualifier matches the corresponding list element; or a dotted
- list that ends in the symbol * (the * matches any number of additional
- qualifiers).
-
- Each applicable method is tested against the qualifier patterns and predicates
- in left-to-right order. As soon as a qualifier pattern matches or a predicate
- returns true, the method becomes a member of the corresponding method group and
- no further tests are made. Thus if a method could be a member of more than one
- method group, it joins only the first such group. If a method group has more
- than one qualifier pattern, a method need only satisfy one of the qualifier
- patterns to be a member of the group.
-
- The name of a predicate function can appear instead of qualifier patterns in a
- method group specifier. The predicate is called for each method that has not
- been assigned to an earlier method group; it is called with one argument, the
- method's qualifier list. The predicate should return true if the method is to
- be a member of the method group. A predicate can be distinguished from a
- qualifier pattern because it is a symbol other than nil or *.
-
- If there is an applicable method whose qualifiers are not valid for the method
- combination type, the function invalid-method-error is called.
-
- Method group specifiers can have keyword options following the qualifier
- patterns or predicate. Keyword options can be distinguished from additional
- qualifier patterns because they are neither lists nor the symbol *. The keyword
- options are:
-
- * The :description option is used to provide a description of the role of
- methods in the method group. Programming environment tools use (apply
- #'format stream format-string (method-qualifiers method)) to print this
- description, which is expected to be concise. This keyword option allows
- the description of a method qualifier to be defined in the same module
- that defines the meaning of the method qualifier. In most cases,
- format-string will not contain any format directives, but they are
- available for generality. If :description is not specified, a default
- description is generated based on the variable name and the qualifier
- patterns and on whether this method group includes the unqualified
- methods. The argument format-string is not evaluated.
-
- * The :order option specifies the order of methods. The order argument is a
- form that evaluates to :most-specific-first or :most-specific-last. If it
- evaluates to any other value, an error is signaled. This keyword option is
- a convenience and does not add any expressive power. If :order is not
- specified, it defaults to :most-specific-first.
-
- * The :required option specifies whether at least one method in this method
- group is required. If the boolean argument is non-nil and the method group
- is empty (that is, no applicable methods match the qualifier patterns or
- satisfy the predicate), an error is signaled. This keyword option is a
- convenience and does not add any expressive power. If :required is not
- specified, it defaults to nil. The boolean argument is not evaluated.
-
- The use of method group specifiers provides a convenient syntax to select
- methods, to divide them among the possible roles, and to perform the necessary
- error checking. It is possible to perform further filtering of methods in the
- body forms by using normal list-processing operations and the functions
- method-qualifiers and invalid-method-error. It is permissible to use setq on
- the variables named in the method group specifiers and to bind additional
- variables. It is also possible to bypass the method group specifier mechanism
- and do everything in the body forms. This is accomplished by writing a single
- method group with * as its only qualifier pattern; the variable is then bound
- to a list of all of the applicable methods, in most-specific-first order.
-
- The body forms compute and return the Lisp form that specifies how the methods
- are combined, that is, the effective method. The effective method uses the
- macro call-method. The definition of this macro has lexical scope and is
- available only in an effective method form. Given a method object in one of the
- lists produced by the method group specifiers and a list of next methods, the
- macro call-method will invoke the method so that call-next-method will have
- available the next methods.
-
- When an effective method has no effect other than to call a single method, some
- implementations employ an optimization that uses the single method directly as
- the effective method, thus avoiding the need to create a new effective method.
- This optimization is active when the effective method form consists entirely of
- an invocation of the call-method macro whose first subform is a method object
- and whose second subform is nil. Each define-method-combination body is
- responsible for stripping off redundant invocations of progn, and,
- multiple-value-prog1, and the like, if this optimization is desired.
-
- The list (:arguments . lambda-list) can appear before any declaration or
- documentation string. This form is useful when the method combination type
- performs some specific behavior as part of the combined method and that
- behavior needs access to the arguments to the generic function. Each parameter
- variable defined by lambda-list is bound to a form that can be inserted into
- the effective method. When this form is evaluated during execution of the
- effective method, its value is the corresponding argument to the generic
- function. If lambda-list is not congruent to the generic function's
- lambda-list, additional ignored parameters are automatically inserted until it
- is congruent. Thus it is permissible for lambda-list to receive fewer arguments
- than the number that the generic function expects.
-
- Erroneous conditions detected by the body should be reported with
- method-combination-error or invalid-method-error; these functions add any
- necessary contextual information to the error message and will signal the
- appropriate error.
-
- The body forms are evaluated inside the bindings created by the lambda-list and
- method group specifiers. Declarations at the head of the body are positioned
- directly inside bindings created by the lambda-list and outside the bindings of
- the method group variables. Thus method group variables cannot be declared.
-
- Within the body forms, generic-function-symbol is bound to the generic function
- object.
-
- If a doc-string argument is present, it provides the documentation for the
- method combination type.
-
- The functions method-combination-error and invalid-method-error can be called
- from the body forms or from functions called by the body forms. The actions of
- these two functions can depend on implementation-dependent dynamic variables
- automatically bound before the generic function compute-effective-method is
- called.
-
- Note that two methods with identical specializers, but with different
- qualifiers, are not ordered by the algorithm described in step 2 of the method
- selection and combination process described in section 28.1.7. Normally the two
- methods play different roles in the effective method because they have
- different qualifiers, and no matter how they are ordered in the result of step
- 2 the effective method is the same. If the two methods play the same role and
- their order matters, an error is signaled. This happens as part of the
- qualifier pattern matching in define-method-combination.
-
- The value returned by the define-method-combination macro is the new method
- combination object.
-
- Most examples of the long form of define-method-combination also illustrate the
- use of the related functions that are provided as part of the declarative
- method combination facility.
-
- ;;; Examples of the short form of define-method-combination
-
- (define-method-combination and :identity-with-one-argument t)
-
- (defmethod func and ((x class1) y)
- ...)
-
- ;;; The equivalent of this example in the long form is:
-
- (define-method-combination and
- (&optional (order ':most-specific-first))
- ((around (:around))
- (primary (and) :order order :required t))
- (let ((form (if (rest primary)
- `(and ,@(mapcar #'(lambda (method)
- `(call-method ,method ()))
- primary))
- `(call-method ,(first primary) ()))))
- (if around
- `(call-method ,(first around)
- (,@(rest around)
- (make-method ,form)))
- form)))
-
- ;;; Examples of the long form of define-method-combination
-
- ;;; The default method-combination technique
-
- (define-method-combination standard ()
- ((around (:around))
- (before (:before))
- (primary () :required t)
- (after (:after)))
- (flet ((call-methods (methods)
- (mapcar #'(lambda (method)
- `(call-method ,method ()))
- methods)))
- (let ((form (if (or before after (rest primary))
- `(multiple-value-prog1
- (progn ,@(call-methods before)
- (call-method ,(first primary)
- ,(rest primary)))
- ,@(call-methods (reverse after)))
- `(call-method ,(first primary) ()))))
- (if around
- `(call-method ,(first around)
- (,@(rest around)
- (make-method ,form)))
- form))))
-
- ;;; A simple way to try several methods until one returns non-nil
-
- (define-method-combination or ()
- ((methods (or)))
- `(or ,@(mapcar #'(lambda (method)
- `(call-method ,method ()))
- methods)))
-
- ;;; A more complete version of the preceding
-
- (define-method-combination or
- (&optional (order ':most-specific-first))
- ((around (:around))
- (primary (or)))
- ;; Process the order argument
- (case order
- (:most-specific-first)
- (:most-specific-last (setq primary (reverse primary)))
- (otherwise (method-combination-error
- "~S is an invalid order.~@
- :most-specific-first and :most-specific-last ~
- are the possible values."
- order)))
- ;; Must have a primary method
- (unless primary
- (method-combination-error "A primary method is required."))
- ;; Construct the form that calls the primary methods
- (let ((form (if (rest primary)
- `(or ,@(mapcar #'(lambda (method)
- `(call-method ,method ()))
- primary))
- `(call-method ,(first primary) ()))))
- ;; Wrap the around methods around that form
- (if around
- `(call-method ,(first around)
- (,@(rest around)
- (make-method ,form)))
- form)))
-
- ;;; The same thing, using the :order and :required keyword options
- (define-method-combination or
- (&optional (order ':most-specific-first))
- ((around (:around))
- (primary (or) :order order :required t))
- (let ((form (if (rest primary)
- `(or ,@(mapcar #'(lambda (method)
- `(call-method ,method ()))
- primary))
- `(call-method ,(first primary) ()))))
- (if around
- `(call-method ,(first around)
- (,@(rest around)
- (make-method ,form)))
- form)))
-
- ;;; This short-form call is behaviorally identical to the preceding.
- (define-method-combination or :identity-with-one-argument t)
-
- ;;; Order methods by positive integer qualifiers; note that :around
- ;;; methods are disallowed here in order to keep the example small.
-
- (define-method-combination example-method-combination ()
- ((methods positive-integer-qualifier-p))
- `(progn ,@(mapcar #'(lambda (method)
- `(call-method ,method ()))
- (stable-sort methods #'<
- :key #'(lambda (method)
- (first (method-qualifiers
- method)))))))
-
- (defun positive-integer-qualifier-p (method-qualifiers)
- (and (= (length method-qualifiers) 1)
- (typep (first method-qualifiers) '(integer 0 *))))
-
- ;;; Example of the use of :arguments
- (define-method-combination progn-with-lock ()
- ((methods ()))
- (:arguments object)
- `(unwind-protect
- (progn (lock (object-lock ,object))
- ,@(mapcar #'(lambda (method)
- `(call-method ,method ()))
- methods))
- (unlock (object-lock ,object))))
-
- The :method-combination option of defgeneric is used to specify that a generic
- function should use a particular method combination type. The argument to the
- :method-combination option is the name of a method combination type.
-
- See sections 28.1.7 and 28.1.7.4 as well as call-method, method-qualifiers,
- method-combination-error, invalid-method-error, and defgeneric.
-
- [Macro]
-
- defmethod function-name {method-qualifier}*
- specialized-lambda-list
- [[ {declaration}* | doc-string]]
- {form}*
-
- function-name ::= {symbol | (setf symbol)}
- method-qualifier ::= non-nil-atom
- parameter-specializer-name ::= symbol | (eql eql-specializer-form)
-
- The macro defmethod defines a method on a generic function.
-
- If (fboundp function-name) is nil, a generic function is created with default
- values for the argument precedence order (each argument is more specific than
- the arguments to its right in the argument list), for the generic function
- class (the class standard-generic-function), for the method class (the class
- standard-method), and for the method combination type (the standard method
- combination type). The lambda-list of the generic function is congruent with
- the lambda-list of the method being defined; if the defmethod form mentions
- keyword arguments, the lambda-list of the generic function will mention &key
- (but no keyword arguments). If function-name names a non-generic function, a
- macro, or a special form, an error is signaled.
-
- If a generic function is currently named by function-name, where function-name
- is a symbol or a list of the form (setf symbol), the lambda-list of the method
- must be congruent with the lambda-list of the generic function. If this
- condition does not hold, an error is signaled. See section 28.1.6.4 for a
- definition of congruence in this context.
-
- The function-name argument is a non-nil symbol or a list of the form (setf
- symbol). It names the generic function on which the method is defined.
-
- Each method-qualifier argument is an object that is used by method combination
- to identify the given method. A method qualifier is a non-nil atom. The method
- combination type may further restrict what a method qualifier may be. The
- standard method combination type allows for unqualified methods or methods
- whose sole qualifier is the keyword :before, the keyword :after, or the keyword
- :around.
-
- A specialized-lambda-list is like an ordinary function lambda-list except that
- the name of a required parameter can be replaced by a specialized parameter, a
- list of the form (variable-name parameter-specializer-name). Only required
- parameters may be specialized. A parameter specializer name is a symbol that
- names a class or (eql eql-specializer-form). The parameter specializer name
- (eql eql-specializer-form) indicates that the corresponding argument must be
- eql to the object that is the value of eql-specializer-form for the method to
- be applicable. If no parameter specializer name is specified for a given
- required parameter, the parameter specializer defaults to the class named t.
- See section 28.1.6.2.
-
- The form arguments specify the method body. The body of the method is enclosed
- in an implicit block. If function-name is a symbol, this block bears the same
- name as the generic function. If function-name is a list of the form (setf
- symbol), the name of the block is symbol.
-
- The result of defmethod is the method object.
-
- The class of the method object that is created is that given by the method
- class option of the generic function on which the method is defined.
-
- If the generic function already has a method that agrees with the method being
- defined on parameter specializers and qualifiers, defmethod replaces the
- existing method with the one now being defined. See section 28.1.6.3 for a
- definition of agreement in this context.
-
- The parameter specializers are derived from the parameter specializer names as
- described in section 28.1.6.2.
-
- The expansion of the defmethod macro refers to each specialized parameter (see
- the ignore declaration specifier), including parameters that have an explicit
- parameter specializer name of t. This means that a compiler warning does not
- occur if the body of the method does not refer to a specialized parameter. Note
- that a parameter that specializes on t is not synonymous with an unspecialized
- parameter in this context.
-
- See sections 28.1.6.2, 28.1.6.4, and 28.1.6.3.
-
- [At this point the original CLOS report [5,7] contained a specification for
- describe as a generic function. This specification is omitted here because
- X3J13 voted in March 1989 (DESCRIBE-UNDERSPECIFIED) not to make describe a
- generic function after all (see describe-object).-GLS]
-
- [Generic function]
- documentation x &optional doc-type
-
- [Primary method]
-
- documentation (method standard-method) &optional doc-type
- documentation (generic-function standard-generic-function)
- &optional doc-type
- documentation (class standard-class) &optional doc-type
- documentation (method-combination method-combination)
- &optional doc-type
- documentation (slot-description standard-slot-description)
- &optional doc-type
- documentation (symbol symbol) &optional doc-type
- documentation (list list) &optional doc-type
-
- The ordinary function documentation (see section 25.2) is replaced by a generic
- function. The generic function documentation returns the documentation string
- associated with the given object if it is available; otherwise documentation
- returns nil.
-
- The first argument of documentation is a symbol, a function-name list of the
- form (setf symbol), a method object, a class object, a generic function object,
- a method combination object, or a slot description object. Whether a second
- argument should be supplied depends on the type of the first argument.
-
- * If the first argument is a method object, a class object, a generic
- function object, a method combination object, or a slot description
- object, the second argument must not be supplied, or an error is signaled.
-
- * If the first argument is a symbol or a list of the form (setf symbol),
- the second argument must be supplied.
-
- o The forms
-
- (documentation symbol 'function)
-
- and
-
- (documentation '(setf symbol) 'function)
-
- return the documentation string of the function, generic function,
- special form, or macro named by the symbol or list.
-
- o The form (documentation symbol 'variable) returns the documentation
- string of the special variable or constant named by the symbol.
-
- o The form (documentation symbol 'structure) returns the documentation
- string of the defstruct structure named by the symbol.
-
- o The form (documentation symbol 'type) returns the documentation
- string of the class object named by the symbol, if there is such a
- class. If there is no such class, it returns the documentation string
- of the type specifier named by the symbol.
-
- o The form (documentation symbol 'setf) returns the documentation
- string of the defsetf or define-setf-method definition associated
- with the symbol.
-
- o The form (documentation symbol 'method-combination) returns the
- documentation string of the method combination type named by the
- symbol.
-
- An implementation may extend the set of symbols that are acceptable as the
- second argument. If a symbol is not recognized as an acceptable argument by the
- implementation, an error must be signaled.
-
- The documentation string associated with the given object is returned unless
- none is available, in which case documentation returns nil.
-
- [Generic function]
- (setf documentation) new-value x &optional doc-type
-
- [Primary method]
-
- (setf documentation) new-value
- (method standard-method) &optional doc-type
- (setf documentation) new-value
- (generic-function standard-generic-function) &optional doc-type
- (setf documentation) new-value
- (class standard-class) &optional doc-type
- (setf documentation) new-value
- (method-combination method-combination) &optional doc-type
- (setf documentation) new-value
- (slot-description standard-slot-description) &optional doc-type
- (setf documentation) new-value
- (symbol symbol) &optional doc-type
- (setf documentation) new-value
- (list list) &optional doc-type
-
- The generic function (setf documentation) is used to update the documentation.
-
- The first argument of (setf documentation) is the new documentation.
-
- The second argument of documentation is a symbol, a function-name list of the
- form (setf symbol), a method object, a class object, a generic function object,
- a method combination object, or a slot description object. Whether a third
- argument should be supplied depends on the type of the second argument. See
- documentation.
-
- [Function]
- ensure-generic-function function-name &key
- :lambda-list:argument-precedence-order:declare:documentation:generic-function-class:method-combination:method-class:environment
-
- function-name ::= {symbol | (setf symbol)}
-
- The function ensure-generic-function is used to define a globally named generic
- function with no methods or to specify or modify options and declarations that
- pertain to a globally named generic function as a whole.
-
- If (fboundp function-name) is nil, a new generic function is created. If
- (fdefinition function-name) is a non-generic function, a macro, or a special
- form, an error is signaled.
-
- [X3J13 voted in March 1989 (FUNCTION-NAME) to use fdefinition in the previous
- paragraph, as shown, rather than symbol-function, as it appeared in the
- original report on CLOS [5,7]. The vote also changed all occurrences of
- function-specifier in the original report to function-name; this change is
- reflected here.-GLS]
-
- If function-name specifies a generic function that has a different value for
- any of the following arguments, the generic function is modified to have the
- new value: :argument-precedence-order, :declare, :documentation,
- :method-combination.
-
- If function-name specifies a generic function that has a different value for
- the :lambda-list argument, and the new value is congruent with the lambda-lists
- of all existing methods or there are no methods, the value is changed;
- otherwise an error is signaled.
-
- If function-name specifies a generic function that has a different value for
- the :generic-function-class argument and if the new generic function class is
- compatible with the old, change-class is called to change the class of the
- generic function; otherwise an error is signaled.
-
- If function-name specifies a generic function that has a different
- :method-class value, the value is changed but any existing methods are not
- changed.
-
- The function-name argument is a symbol or a list of the form (setf symbol).
-
- The keyword arguments correspond to the option arguments of defgeneric, except
- that the :method-class and :generic-function-class arguments can be class
- objects as well as names.
-
- The :environment argument is the same as the &environment argument to macro
- expansion functions. It is typically used to distinguish between compile-time
- and run-time environments.
-
- The :method-combination argument is a method combination object.
-
- The generic function object is returned. See defgeneric.
-
- [Function]
- find-class symbol &optional errorp environment
-
- The function find-class returns the class object named by the given symbol in
- the given environment.
-
- The first argument to find-class is a symbol.
-
- If there is no such class and the errorp argument is not supplied or is
- non-nil, find-class signals an error. If there is no such class and the errorp
- argument is nil, find-class returns nil. The default value of errorp is t.
-
- The optional environment argument is the same as the &environment argument to
- macro expansion functions. It is typically used to distinguish between
- compile-time and run-time environments.
-
- The result of find-class is the class object named by the given symbol.
-
- The class associated with a particular symbol can be changed by using setf with
- find-class. The results are undefined if the user attempts to change the class
- associated with a symbol that is defined as a type specifier in chapter 4. See
- section 28.1.4.
-
- [Generic function]
- find-method generic-function method-qualifiers specializers &optional errorp
-
- [Primary method]
-
- find-method (generic-function standard-generic-function)
- method-qualifiers specializers &optional errorp
-
- The generic function find-method takes a generic function and returns the
- method object that agrees on method qualifiers and parameter specializers with
- the method-qualifiers and specializers arguments of find-method. See section
- 28.1.6.3 for a definition of agreement in this context.
-
- The generic-function argument is a generic function.
-
- The method-qualifiers argument is a list of the method qualifiers for the
- method. The order of the method qualifiers is significant.
-
- The specializers argument is a list of the parameter specializers for the
- method. It must correspond in length to the number of required arguments of the
- generic function, or an error is signaled. This means that to obtain the
- default method on a given generic function, a list whose elements are the class
- named t must be given.
-
- If there is no such method and the errorp argument is not supplied or is
- non-nil, find-method signals an error. If there is no such method and the
- errorp argument is nil, find-method returns nil. The default value of errorp is
- t.
-
- The result of find-method is the method object with the given method qualifiers
- and parameter specializers.
-
- See section 28.1.6.3.
-
- [Generic function]
- function-keywords method
-
- [Primary method]
- function-keywords (method standard-method)
-
- The generic function function-keywords is used to return the keyword parameter
- specifiers for a given method.
-
- The method argument is a method object.
-
- The generic function function-keywords returns two values: a list of the
- explicitly named keywords and a boolean that states whether &allow-other-keys
- had been specified in the method definition.
-
- [Special Form]
-
- generic-flet ({(function-name lambda-list
- [[?option | {method-description}* ]])}*)
- {form}*
-
- The generic-flet special form is analogous to the flet special form. It
- produces new generic functions and establishes new lexical function definition
- bindings. Each generic function is created with the set of methods specified by
- its method descriptions.
-
- The special form generic-flet is used to define generic functions whose names
- are meaningful only locally and to execute a series of forms with these
- function definition bindings. Any number of such local generic functions may be
- defined.
-
- The names of functions defined by generic-flet have lexical scope; they retain
- their local definitions only within the body of the generic-flet. Any
- references within the body of the generic-flet to functions whose names are the
- same as those defined within the generic-flet are thus references to the local
- functions instead of to any global functions of the same names. The scope of
- these generic function definition bindings, however, includes only the body of
- generic-flet, not the definitions themselves. Within the method bodies, local
- function names that match those being defined refer to global functions defined
- outside the generic-flet. It is thus not possible to define recursive functions
- with generic-flet.
-
- The function-name, lambda-list, option, method-qualifier, and
- specialized-lambda-list arguments are the same as for defgeneric.
-
- A generic-flet local method definition is identical in form to the method
- definition part of a defmethod.
-
- The body of each method is enclosed in an implicit block. If function-name is a
- symbol, this block bears the same name as the generic function. If
- function-name is a list of the form (setf symbol), the name of the block is
- symbol.
-
- The result returned by generic-flet is the value or values returned by the last
- form executed. If no forms are specified, generic-flet returns nil.
-
- See generic-labels, defmethod, defgeneric, and generic-function.
-
- [Macro]
-
- generic-function lambda-list [[?option | {method-description}*]]
-
- option ::= (:argument-precedence-order {parameter-name}+)
- | (declare {declaration}+)
- | (:documentation string)
- | (:method-combination symbol {arg}*)
- | (:generic-function-class class-name)
- | (:method-class class-name)
- method-description ::= (:method {method-qualifier}*
- specialized-lambda-list
- {declaration | documentation}*
- {form}*)
-
- The generic-function macro creates an anonymous generic function. The generic
- function is created with the set of methods specified by its method
- descriptions.
-
- The option, method-qualifier, and specialized-lambda-list arguments are the
- same as for defgeneric.
-
- The generic function object is returned as the result.
-
- If no method descriptions are specified, an anonymous generic function with no
- methods is created.
-
- See defgeneric, generic-flet, generic-labels, and defmethod.
-
- [Special Form]
-
- generic-labels ((function-name lambda-list
- [[?option | {method-description}*]])}*)
- {form}*
-
- The generic-labels special form is analogous to the labels special form. It
- produces new generic functions and establishes new lexical function definition
- bindings. Each generic function is created with the set of methods specified by
- its method descriptions.
-
- The special form generic-labels is used to define generic functions whose names
- are meaningful only locally and to execute a series of forms with these
- function definition bindings. Any number of such local generic functions may be
- defined.
-
- The names of functions defined by generic-labels have lexical scope; they
- retain their local definitions only within the body of the generic-labels
- construct. Any references within the body of the generic-labels construct to
- functions whose names are the same as those defined within the generic-labels
- form are thus references to the local functions instead of to any global
- functions of the same names. The scope of these generic function definition
- bindings includes the method bodies themselves as well as the body of the
- generic-labels construct.
-
- The function-name, lambda-list, option, method-qualifier, and
- specialized-lambda-list arguments are the same as for defgeneric.
-
- A generic-labels local method definition is identical in form to the method
- definition part of a defmethod.
-
- The body of each method is enclosed in an implicit block. If function-name is a
- symbol, this block bears the same name as the generic function. If
- function-name is a list of the form (setf symbol), the name of the block is
- symbol.
-
- The result returned by generic-labels is the value or values returned by the
- last form executed. If no forms are specified, generic-labels returns nil.
-
- See generic-flet, defmethod, defgeneric, generic-function.
-
- [Generic function]
- initialize-instance instance &rest initargs
-
- [Primary method]
- initialize-instance (instance standard-object) &rest initargs
-
- The generic function initialize-instance is called by make-instance to
- initialize a newly created instance. The generic function initialize-instance
- is called with the new instance and the defaulted initialization arguments.
-
- The system-supplied primary method on initialize-instance initializes the slots
- of the instance with values according to the initialization arguments and the
- :initform forms of the slots. It does this by calling the generic function
- shared-initialize with the following arguments: the instance, t (this indicates
- that all slots for which no initialization arguments are provided should be
- initialized according to their :initform forms) and the defaulted
- initialization arguments.
-
- The instance argument is the object to be initialized.
-
- The initargs argument consists of alternating initialization argument names and
- values.
-
- The modified instance is returned as the result.
-
- Programmers can define methods for initialize-instance to specify actions to be
- taken when an instance is initialized. If only :after methods are defined, they
- will be run after the system-supplied primary method for initialization and
- therefore will not interfere with the default behavior of initialize-instance.
-
- See sections 28.1.9, 28.1.9.4, and 28.1.9.2 as well as shared-initialize,
- make-instance, slot-boundp, and slot-makunbound.
-
- [Function]
- invalid-method-error method format-string &rest args
-
- The function invalid-method-error is used to signal an error when there is an
- applicable method whose qualifiers are not valid for the method combination
- type. The error message is constructed by using a format string and any
- arguments to it. Because an implementation may need to add additional
- contextual information to the error message, invalid-method-error should be
- called only within the dynamic extent of a method combination function.
-
- The function invalid-method-error is called automatically when a method fails
- to satisfy every qualifier pattern and predicate in a define-method-combination
- form. A method combination function that imposes additional restrictions should
- call invalid-method-error explicitly if it encounters a method it cannot
- accept.
-
- The method argument is the invalid method object.
-
- The format-string argument is a control string that can be given to format, and
- args are any arguments required by that string.
-
- Whether invalid-method-error returns to its caller or exits via throw is
- implementation-dependent.
-
- See define-method-combination.
-
- [Generic function]
- make-instance class &rest initargs
-
- [Primary method]
- make-instance (class standard-class) &rest initargs
- make-instance (class symbol) &rest initargs
-
- The generic function make-instance creates a new instance of the given class.
-
- The generic function make-instance may be used as described in section 28.1.9.
-
- The class argument is a class object or a symbol that names a class. The
- remaining arguments form a list of alternating initialization argument names
- and values.
-
- If the second of the preceding methods is selected, that method invokes
- make-instance on the arguments (find-class class) and initargs.
-
- The initialization arguments are checked within make-instance (see section
- 28.1.9).
-
- The new instance is returned.
-
- The meta-object protocol can be used to define new methods on make-instance to
- replace the object-creation protocol.
-
- See section 28.1.9 as well as defclass, initialize-instance, and class-of.
-
- [Generic function]
- make-instances-obsolete class
-
- [Primary method]
- make-instances-obsolete (class standard-class)
- make-instances-obsolete (class symbol)
-
- The generic function make-instances-obsolete is invoked automatically by the
- system when defclass has been used to redefine an existing standard class and
- the set of local slots accessible in an instance is changed or the order of
- slots in storage is changed. It can also be explicitly invoked by the user.
-
- The function make-instances-obsolete has the effect of initiating the process
- of updating the instances of the class. During updating, the generic function
- update-instance-for-redefined-class will be invoked.
-
- The class argument is a class object symbol that names the class whose
- instances are to be made obsolete.
-
- If the second of the preceding methods is selected, that method invokes
- make-instances-obsolete on (find-class class).
-
- The modified class is returned. The result of make-instances-obsolete is eq to
- the class argument supplied to the first of the preceding methods.
-
- See section 28.1.10 as well as update-instance-for-redefined-class.
-
- [Function]
- method-combination-error format-string &rest args
-
- The function method-combination-error is used to signal an error in method
- combination. The error message is constructed by using a format string and any
- arguments to it. Because an implementation may need to add additional
- contextual information to the error message, method-combination-error should be
- called only within the dynamic extent of a method combination function.
-
- The format-string argument is a control string that can be given to format, and
- args are any arguments required by that string.
-
- Whether method-combination-error returns to its caller or exits via throw is
- implementation-dependent.
-
- See define-method-combination.
-
- [Generic function]
- method-qualifiers method
-
- [Primary method]
- method-qualifiers (method standard-method)
-
- The generic function method-qualifiers returns a list of the qualifiers of the
- given method.
-
- The method argument is a method object.
-
- A list of the qualifiers of the given method is returned.
-
- Example:
-
- (setq methods (remove-duplicates methods
- :from-end t
- :key #'method-qualifiers
- :test #'equal))
-
- See define-method-combination.
-
- [Function]
- next-method-p
-
- The locally defined function next-method-p can be used within the body of a
- method defined by a method-defining form to determine whether a next method
- exists.
-
- The function next-method-p takes no arguments.
-
- The function next-method-p returns true or false.
-
- Like call-next-method, the function next-method-p has lexical scope (for it is
- defined only within the body of a method defined by a method-defining form) and
- indefinite extent.
-
- See call-next-method.
-
- [Generic function]
- no-applicable-method generic-function &rest function-arguments
-
- [Primary method]
- no-applicable-method (generic-function t) &rest function-arguments
-
- The generic function no-applicable-method is called when a generic function of
- the class standard-generic-function is invoked and no method on that generic
- function is applicable. The default method signals an error.
-
- The generic function no-applicable-method is not intended to be called by
- programmers. Programmers may write methods for it.
-
- The generic-function argument of no-applicable-method is the generic function
- object on which no applicable method was found.
-
- The function-arguments argument is a list of the arguments to that generic
- function.
-
- [Generic function]
- no-next-method generic-function method &rest args
-
- [Primary method]
-
- no-next-method (generic-function standard-generic-function)
- (method standard-method) &rest args
-
- The generic function no-next-method is called by call-next-method when there is
- no next method. The system-supplied method on no-next-method signals an error.
-
- The generic function no-next-method is not intended to be called by
- programmers. Programmers may write methods for it.
-
- The generic-function argument is the generic function object to which the
- method that is the second argument belongs.
-
- The method argument is the method that contains the call to call-next-method
- for which there is no next method.
-
- The args argument is a list of the arguments to call-next-method.
-
- See call-next-method.
-
- [Generic function]
- print-object object stream
-
- [Primary method]
- print-object (object standard-object) stream
-
- The generic function print-object writes the printed representation of an
- object to a stream. The function print-object is called by the print system; it
- should not be called by the user.
-
- Each implementation must provide a method on the class standard-object and
- methods on enough other classes so as to ensure that there is always an
- applicable method. Implementations are free to add methods for other classes.
- Users can write methods for print-object for their own classes if they do not
- wish to inherit an implementation-supplied method.
-
- The first argument is any Lisp object. The second argument is a stream; it
- cannot be t or nil.
-
- The function print-object returns its first argument, the object.
-
- Methods on print-object must obey the print control special variables named
- *print-xxx* for various xxx. The specific details are the following:
-
- * Each method must implement *print-escape*.
-
- * The *print-pretty* control variable can be ignored by most methods other
- than the one for lists.
-
- * The *print-circle* control variable is handled by the printer and can be
- ignored by methods.
-
- * The printer takes care of *print-level* automatically, provided that each
- method handles exactly one level of structure and calls write (or an
- equivalent function) recursively if there are more structural levels. The
- printer's decision of whether an object has components (and therefore
- should not be printed when the printing depth is not less than
- *print-level*) is implementation-dependent. In some implementations its
- print-object method is not called; in others the method is called, and the
- determination that the object has components is based on what it tries to
- write to the stream.
-
- * Methods that produce output of indefinite length must obey
- *print-length*, but most methods other than the one for lists can ignore
- it.
-
- * The *print-base*, *print-radix*, *print-case*, *print-gensym*, and
- *print-array* control variables apply to specific types of objects and are
- handled by the methods for those objects.
-
- * X3J13 voted in June 1989 (DATA-IO) to add the following point. All
- methods for print-object must obey *print-readably*, which takes
- precedence over all other printer control variables. This includes both
- user-defined methods and implementation-defined methods.
-
- If these rules are not obeyed, the results are undefined.
-
- In general, the printer and the print-object methods should not rebind the
- print control variables as they operate recursively through the structure, but
- this is implementation-dependent.
-
- In some implementations the stream argument passed to a print-object method is
- not the original stream but is an intermediate stream that implements part of
- the printer. Methods should therefore not depend on the identity of this
- stream.
-
- All of the existing printing functions (write, prin1, print, princ, pprint,
- write-to-string, prin1-to-string, princ-to-string, the ~S and ~A format
- operations, and the ~B, ~D, ~E, ~F, ~G, ~$, ~O, ~R, and ~X format operations
- when they encounter a non-numeric value) are required to be changed to go
- through the print-object generic function. Each implementation is required to
- replace its former implementation of printing with one or more print-object
- methods. Exactly which classes have methods for print-object is not specified;
- it would be valid for an implementation to have one default method that is
- inherited by all system-defined classes.
-
- [Generic function]
- reinitialize-instance instance &rest initargs
-
- [Primary method]
- reinitialize-instance (instance standard-object) &rest initargs
-
- The generic function reinitialize-instance can be used to change the values of
- local slots according to initialization arguments. This generic function is
- called by the Meta-Object Protocol. It can also be called by users.
-
- The system-supplied primary method for reinitialize-instance checks the
- validity of initialization arguments and signals an error if an initialization
- argument is supplied that is not declared valid. The method then calls the
- generic function shared-initialize with the following arguments: the instance,
- nil (which means no slots should be initialized according to their :initform
- forms) and the initialization arguments it received.
-
- The instance argument is the object to be initialized.
-
- The initargs argument consists of alternating initialization argument names and
- values.
-
- The modified instance is returned as the result.
-
- Initialization arguments are declared valid by using the :initarg option to
- defclass, or by defining methods for reinitialize-instance or
- shared-initialize. The keyword name of each keyword parameter specifier in the
- lambda-list of any method defined on reinitialize-instance or shared-initialize
- is declared a valid initialization argument name for all classes for which that
- method is applicable.
-
- See sections 28.1.12, 28.1.9.4, 28.1.9.2 as well as initialize-instance,
- slot-boundp, update-instance-for-redefined-class,
- update-instance-for-different-class, slot-makunbound, and shared-initialize.
-
- [Generic function]
- remove-method generic-function method
-
- [Primary method]
- remove-method (generic-function standard-generic-function) method
-
- The generic function remove-method removes a method from a generic function. It
- destructively modifies the specified generic function and returns the modified
- generic function as its result.
-
- The generic-function argument is a generic function object.
-
- The method argument is a method object. The function remove-method does not
- signal an error if the method is not one of the methods on the generic
- function.
-
- The modified generic function is returned. The result of remove-method is eq to
- the generic-function argument.
-
- See find-method.
-
- [Generic function]
- shared-initialize instance slot-names &rest initargs
-
- [Primary method]
-
- shared-initialize (instance standard-object)
- slot-names &rest initargs
-
- The generic function shared-initialize is used to fill the slots of an instance
- using initialization arguments and :initform forms. It is called when an
- instance is created, when an instance is re-initialized, when an instance is
- updated to conform to a redefined class, and when an instance is updated to
- conform to a different class. The generic function shared-initialize is called
- by the system-supplied primary method for initialize-instance,
- reinitialize-instance, update-instance-for-redefined-class, and
- update-instance-for-different-class.
-
- The generic function shared-initialize takes the following arguments: the
- instance to be initialized, a specification of a set of names of slots
- accessible in that instance, and any number of initialization arguments. The
- arguments after the first two must form an initialization argument list. The
- system-supplied primary method on shared-initialize initializes the slots with
- values according to the initialization arguments and specified :initform forms.
- The second argument indicates which slots should be initialized according to
- their :initform forms if no initialization arguments are provided for those
- slots.
-
- The system-supplied primary method behaves as follows, regardless of whether
- the slots are local or shared:
-
- * If an initialization argument in the initialization argument list
- specifies a value for that slot, that value is stored into the slot, even
- if a value has already been stored in the slot before the method is run.
-
- * Any slots indicated by the second argument that are still unbound at this
- point are initialized according to their :initform forms. For any such
- slot that has an :initform form, that form is evaluated in the lexical
- environment of its defining defclass form and the result is stored into
- the slot. For example, if a :before method stores a value in the slot, the
- :initform form will not be used to supply a value for the slot.
-
- * The rules mentioned in section 28.1.9.4 are obeyed.
-
- The instance argument is the object to be initialized.
-
- The slot-names argument specifies the slots that are to be initialized
- according to their :initform forms if no initialization arguments apply. It is
- supplied in one of three forms as follows:
-
- * It can be a list of slot names, which specifies the set of those slot
- names.
-
- * It can be nil, which specifies the empty set of slot names.
-
- * It can be the symbol t, which specifies the set of all of the slots.
-
- The initargs argument consists of alternating initialization argument names and
- values.
-
- The modified instance is returned as the result.
-
- Initialization arguments are declared valid by using the :initarg option to
- defclass, or by defining methods for shared-initialize. The keyword name of
- each keyword parameter specifier in the lambda-list of any method defined on
- shared-initialize is declared a valid initialization argument name for all
- classes for which that method is applicable.
-
- Implementations are permitted to optimize :initform forms that neither produce
- nor depend on side effects by evaluating these forms and storing them into
- slots before running any initialize-instance methods, rather than by handling
- them in the primary initialize-instance method. (This optimization might be
- implemented by having the allocate-instance method copy a prototype instance.)
-
- Implementations are permitted to optimize default initial value forms for
- initialization arguments associated with slots by not actually creating the
- complete initialization argument list when the only method that would receive
- the complete list is the method on standard-object. In this case, default
- initial value forms can be treated like :initform forms. This optimization has
- no visible effects other than a performance improvement.
-
- See sections 28.1.9, 28.1.9.4, 28.1.9.2 as well as initialize-instance,
- reinitialize-instance, update-instance-for-redefined-class,
- update-instance-for-different-class, slot-boundp, and slot-makunbound.
-
- [Function]
- slot-boundp instance slot-name
-
- The function slot-boundp tests whether a specific slot in an instance is bound.
-
- The arguments are the instance and the name of the slot.
-
- The function slot-boundp returns true or false.
-
- This function allows for writing :after methods on initialize-instance in order
- to initialize only those slots that have not already been bound.
-
- If no slot of the given name exists in the instance, slot-missing is called as
- follows:
-
- (slot-missing (class-of instance)
- instance
- slot-name
- 'slot-boundp)
-
- The function slot-boundp is implemented using slot-boundp-using-class. See
- slot-missing.
-
- [Function]
- slot-exists-p object slot-name
-
- The function slot-exists-p tests whether the specified object has a slot of the
- given name.
-
- The object argument is any object. The slot-name argument is a symbol.
-
- The function slot-exists-p returns true or false.
-
- The function slot-exists-p is implemented using slot-exists-p-using-class.
-
- [Function]
- slot-makunbound instance slot-name
-
- The function slot-makunbound restores a slot in an instance to the unbound
- state.
-
- The arguments to slot-makunbound are the instance and the name of the slot.
-
- The instance is returned as the result.
-
- If no slot of the given name exists in the instance, slot-missing is called as
- follows:
-
- (slot-missing (class-of instance)
- instance
- slot-name
- 'slot-makunbound)
-
- The function slot-makunbound is implemented using slot-makunbound-using-class.
- See slot-missing.
-
- [Generic function]
- slot-missing class object slot-name operation &optional new-value
-
- [Primary method]
- slot-missing (class t) object slot-name operation &optional new-value
-
- The generic function slot-missing is invoked when an attempt is made to access
- a slot in an object whose metaclass is standard-class and the name of the slot
- provided is not a name of a slot in that class. The default method signals an
- error.
-
- The generic function slot-missing is not intended to be called by programmers.
- Programmers may write methods for it.
-
- The required arguments to slot-missing are the class of the object that is
- being accessed, the object, the slot name, and a symbol that indicates the
- operation that caused slot-missing to be invoked. The optional argument to
- slot-missing is used when the operation is attempting to set the value of the
- slot.
-
- If a method written for slot-missing returns values, these values get returned
- as the values of the original function invocation.
-
- The generic function slot-missing may be called during evaluation of
- slot-value, (setf slot-value), slot-boundp, and slot-makunbound. For each of
- these operations the corresponding symbol for the operation argument is
- slot-value, setf, slot-boundp, and slot-makunbound, respectively.
-
- The set of arguments (including the class of the instance) facilitates defining
- methods on the metaclass for slot-missing.
-
- [Generic function]
- slot-unbound class instance slot-name
-
- [Primary method]
- slot-unbound (class t) instance slot-name
-
- The generic function slot-unbound is called when an unbound slot is read in an
- instance whose metaclass is standard-class. The default method signals an
- error.
-
- The generic function slot-unbound is not intended to be called by programmers.
- Programmers may write methods for it. The function slot-unbound is called only
- by the function slot-value-using-class and thus indirectly by slot-value.
-
- The arguments to slot-unbound are the class of the instance whose slot was
- accessed, the instance itself, and the name of the slot.
-
- If a method written for slot-unbound returns values, these values get returned
- as the values of the original function invocation.
-
- An unbound slot may occur if no :initform form was specified for the slot and
- the slot value has not been set, or if slot-makunbound has been called on the
- slot.
-
- See slot-makunbound.
-
- [Function]
- slot-value object slot-name
-
- The function slot-value returns the value contained in the slot slot-name of
- the given object. If there is no slot with that name, slot-missing is called.
- If the slot is unbound, slot-unbound is called.
-
- The macro setf can be used with slot-value to change the value of a slot.
-
- The arguments are the object and the name of the given slot.
-
- The result is the value contained in the given slot.
-
- If an attempt is made to read a slot and no slot of the given name exists in
- the instance, slot-missing is called as follows:
-
- (slot-missing (class-of instance)
- instance
- slot-name
- 'slot-value)
-
- If an attempt is made to write a slot and no slot of the given name exists in
- the instance, slot-missing is called as follows:
-
- (slot-missing (class-of instance)
- instance
- slot-name
- 'setf
- new-value)
-
- The function slot-value is implemented using slot-value-using-class.
-
- Implementations may optimize slot-value by compiling it in-line.
-
- See slot-missing and slot-unbound.
-
- [At this point the original CLOS report [5,7] contained a specification for
- symbol-macrolet. This specification is omitted here. Instead, a description of
- symbol-macrolet appears with those of related constructs in chapter 7.-GLS]
-
- [Generic function]
- update-instance-for-different-class previous current &rest initargs
-
- [Primary method]
-
- update-instance-for-different-class (previous standard-object)
- (current standard-object) &rest initargs
-
- The generic function update-instance-for-different-class is not intended to be
- called by programmers. Programmers may write methods for it. This function is
- called only by the function change-class.
-
- The system-supplied primary method on update-instance-for-different-class
- checks the validity of initialization arguments and signals an error if an
- initialization argument is supplied that is not declared valid. This method
- then initializes slots with values according to the initialization arguments
- and initializes the newly added slots with values according to their :initform
- forms. It does this by calling the generic function shared-initialize with the
- following arguments: the instance, a list of names of the newly added slots,
- and the initialization arguments it received. Newly added slots are those local
- slots for which no slot of the same name exists in the previous class.
-
- Methods for update-instance-for-different-class can be defined to specify
- actions to be taken when an instance is updated. If only :after methods for
- update-instance-for-different-class are defined, they will be run after the
- system-supplied primary method for initialization and therefore will not
- interfere with the default behavior of update-instance-for-different-class.
-
- The arguments to update-instance-for-different-class are computed by
- change-class. When change-class is invoked on an instance, a copy of that
- instance is made; change-class then destructively alters the original instance.
- The first argument to update-instance-for-different-class, previous, is that
- copy; it holds the old slot values temporarily. This argument has dynamic
- extent within change-class; if it is referenced in any way once
- update-instance-for-different-class returns, the results are undefined. The
- second argument to update-instance-for-different-class, current, is the altered
- original instance.
-
- The intended use of previous is to extract old slot values by using slot-value
- or with-slots or by invoking a reader generic function, or to run other methods
- that were applicable to instances of the original class.
-
- The initargs argument consists of alternating initialization argument names and
- values.
-
- The value returned by update-instance-for-different-class is ignored by
- change-class.
-
- See the example for the function change-class.
-
- Initialization arguments are declared valid by using the :initarg option to
- defclass, or by defining methods for update-instance-for-different-class or
- shared-initialize. The keyword name of each keyword parameter specifier in the
- lambda-list of any method defined on update-instance-for-different-class or
- shared-initialize is declared a valid initialization argument name for all
- classes for which that method is applicable.
-
- Methods on update-instance-for-different-class can be defined to initialize
- slots differently from change-class. The default behavior of change-class is
- described in section 28.1.11.
-
- See sections 28.1.11, 28.1.9.4, and 28.1.9.2 as well as change-class and
- shared-initialize.
-
- [Generic function]
-
- update-instance-for-redefined-class instance
- added-slots discarded-slots property-list
- &rest initargs
-
- [Primary method]
-
- update-instance-for-redefined-class (instance standard-object)
- added-slots discarded-slots property-list
- &rest initargs
-
- The generic function update-instance-for-redefined-class is not intended to be
- called by programmers. Programmers may write methods for it. The generic
- function update-instance-for-redefined-class is called by the mechanism
- activated by make-instances-obsolete.
-
- The system-supplied primary method on update-instance-for-different-class
- checks the validity of initialization arguments and signals an error if an
- initialization argument is supplied that is not declared valid. This method
- then initializes slots with values according to the initialization arguments
- and initializes the newly added slots with values according to their :initform
- forms. It does this by calling the generic function shared-initialize with the
- following arguments: the instance, a list of names of the newly added slots,
- and the initialization arguments it received. Newly added slots are those local
- slots for which no slot of the same name exists in the old version of the
- class.
-
- When make-instances-obsolete is invoked or when a class has been redefined and
- an instance is being updated, a property list is created that captures the slot
- names and values of all the discarded slots with values in the original
- instance. The structure of the instance is transformed so that it conforms to
- the current class definition. The arguments to
- update-instance-for-redefined-class are this transformed instance, a list of
- the names of the new slots added to the instance, a list of the names of the
- old slots discarded from the instance, and the property list containing the
- slot names and values for slots that were discarded and had values. Included in
- this list of discarded slots are slots that were local in the old class and are
- shared in the new class.
-
- The initargs argument consists of alternating initialization argument names and
- values.
-
- The value returned by update-instance-for-redefined-class is ignored.
-
- Initialization arguments are declared valid by using the :initarg option to
- defclass or by defining methods for update-instance-for-redefined-class or
- shared-initialize. The keyword name of each keyword parameter specifier in the
- lambda-list of any method defined on update-instance-for-redefined-class or
- shared-initialize is declared a valid initialization argument name for all
- classes for which that method is applicable.
-
- See sections 28.1.10, 28.1.9.4, and 28.1.9.2 as well as shared-initialize and
- make-instances-obsolete.
-
- (defclass position () ())
-
- (defclass x-y-position (position)
- ((x :initform 0 :accessor position-x)
- (y :initform 0 :accessor position-y)))
-
- ;;; It turns out polar coordinates are used more than Cartesian
- ;;; coordinates, so the representation is altered and some new
- ;;; accessor methods are added.
-
- (defmethod update-instance-for-redefined-class :before
- ((pos x-y-position) added deleted plist &key)
- ;; Transform the x-y coordinates to polar coordinates
- ;; and store into the new slots.
- (let ((x (getf plist 'x))
- (y (getf plist 'y)))
- (setf (position-rho pos) (sqrt (+ (* x x) (* y y)))
- (position-theta pos) (atan y x))))
-
- (defclass x-y-position (position)
- ((rho :initform 0 :accessor position-rho)
- (theta :initform 0 :accessor position-theta)))
-
- ;;; All instances of the old x-y-position class will be updated
- ;;; automatically.
-
- ;;; The new representation has the look and feel of the old one.
-
- (defmethod position-x ((pos x-y-position))
- (with-slots (rho theta) pos (* rho (cos theta))))
-
- (defmethod (setf position-x) (new-x (pos x-y-position))
- (with-slots (rho theta) pos
- (let ((y (position-y pos)))
- (setq rho (sqrt (+ (* new-x new-x) (* y y)))
- theta (atan y new-x))
- new-x)))
-
- (defmethod position-y ((pos x-y-position))
- (with-slots (rho theta) pos (* rho (sin theta))))
-
- (defmethod (setf position-y) (new-y (pos x-y-position))
- (with-slots (rho theta) pos
- (let ((x (position-x pos)))
- (setq rho (sqrt (+ (* x x) (* new-y new-y)))
- theta (atan new-y x))
- new-y)))
-
- [Macro]
-
- with-accessors ({slot-entry}*) instance-form
- {declaration}* {form}*
-
- The macro with-accessors creates a lexical environment in which specified slots
- are lexically available through their accessors as if they were variables. The
- macro with-accessors invokes the appropriate accessors to access the specified
- slots. Both setf and setq can be used to set the value of the slot.
-
- The result returned is that obtained by executing the forms specified by the
- body argument.
-
- Example:
-
- (with-accessors ((x position-x) (y position-y)) p1
- (setq x y))
-
- A with-accessors expression of the form
-
- (with-accessors ( ... ) instance
- ... )
- ... )
-
- expands into the equivalent of
-
- (let ((in instance))
- (symbol-macrolet (( ( in))
- ...
- ( ( in)))
- ... )
- ... )
-
- [X3J13 voted in March 1989 (SYMBOL-MACROLET-SEMANTICS) to modify the
- definition of symbol-macrolet substantially and also voted
- (SYMBOL-MACROLET-DECLARE) to allow declarations before the body of
- symbol-macrolet but with peculiar treatment of special and type declarations.
- The syntactic changes are reflected in this definition of with-accessors.-GLS]
-
- See with-slots and symbol-macrolet.
-
- [Special Form]
-
- with-added-methods (function-name lambda-list
- [[?option | {method-description}*]])
- {form}*
-
- The with-added-methods special form produces new generic functions and
- establishes new lexical function definition bindings. Each generic function is
- created by adding the set of methods specified by its method definitions to a
- copy of the lexically visible generic function of the same name and its
- methods. If such a generic function does not already exist, a new generic
- function is created; this generic function has lexical scope.
-
- The special form with-added-methods is used to define functions whose names are
- meaningful only locally and to execute a series of forms with these function
- definition bindings.
-
- The names of functions defined by with-added-methods have lexical scope; they
- retain their local definitions only within the body of the with-added-methods
- construct. Any references within the body of the with-added-methods construct
- to functions whose names are the same as those defined within the
- with-added-methods form are thus references to the local functions instead of
- to any global functions of the same names. The scope of these generic function
- definition bindings includes the method bodies themselves as well as the body
- of the with-added-methods construct.
-
- The function-name, option, method-qualifier, and specialized-lambda-list
- arguments are the same as for defgeneric.
-
- The body of each method is enclosed in an implicit block. If function-name is a
- symbol, this block bears the same name as the generic function. If
- function-name is a list of the form (setf symbol), the name of the block is
- symbol.
-
- The result returned by with-added-methods is the value or values of the last
- form executed. If no forms are specified, with-added-methods returns nil.
-
- If a generic function with the given name already exists, the lambda-list
- specified in the with-added-methods form must be congruent with the
- lambda-lists of all existing methods on that function as well as with the
- lambda-lists of all methods defined by the with-added-methods form; otherwise
- an error is signaled.
-
- If function-name specifies an existing generic function that has a different
- value for any of the following option arguments, the copy of that generic
- function is modified to have the new value: :argument-precedence-order,
- declare, :documentation, :generic-function-class, :method-combination.
-
- If function-name specifies an existing generic function that has a different
- value for the :method-class option argument, that value is changed in the copy
- of that generic function, but any methods copied from the existing generic
- function are not changed.
-
- If a function of the given name already exists, that function is copied into
- the default method for a generic function of the given name. Note that this
- behavior differs from that of defgeneric.
-
- If a macro or special form of the given name already exists, an error is
- signaled.
-
- If there is no existing generic function, the option arguments have the same
- default values as the option arguments to defgeneric.
-
- See generic-labels, generic-flet, defmethod, defgeneric, and
- ensure-generic-function.
-
- [Macro]
-
- with-slots ({slot-entry}*) instance-form
- {declaration}* {form}*
-
- slot-entry ::= slot-name | (variable-name slot-name)
-
- The macro with-slots creates a lexical context for referring to specified slots
- as though they were variables. Within such a context the value of the slot can
- be specified by using its slot name, as if it were a lexically bound variable.
- Both setf and setq can be used to set the value of the slot.
-
- The macro with-slots translates an appearance of the slot name as a variable
- into a call to slot-value.
-
- The result returned is that obtained by executing the forms specified by the
- body argument.
-
- Example:
-
- (with-slots (x y) position-1
- (sqrt (+ (* x x) (* y y))))
-
- (with-slots ((x1 x) (y1 y)) position-1
- (with-slots ((x2 x) (y2 y)) position-2
- (psetf x1 x2
- y1 y2))))
-
- (with-slots (x y) position
- (setq x (1+ x)
- y (1+ y)))
-
- A with-slots expression of the form:
-
- (with-slots ( ... ) instance
- ... )
- ... )
-
- expands into the equivalent of
-
- (let ((in instance))
- (symbol-macrolet ( ... )
- ... )
- ... )
-
- where is
-
- ( (slot-value in ' ))
-
- if is a symbol and is
-
- ( (slot-value in ' ))
-
- if is of the form ( ).
-
- [X3J13 voted in March 1989 (SYMBOL-MACROLET-SEMANTICS) to modify the
- definition of symbol-macrolet substantially and also voted
- (SYMBOL-MACROLET-DECLARE) to allow declarations before the body of
- symbol-macrolet but with peculiar treatment of special and type declarations.
- The syntactic changes are reflected in this definition of with-slots.-GLS]
-
- See with-accessors and symbol-macrolet.
- [change_end]
-
-
-
-
-
-
-
-
-
-
-
-
-
-